loj 1032 数位dp

时间:2021-09-25 07:40:53

题目链接:http://lightoj.com/volume_showproblem.php?problem=1032

思路:数位dp, 采用记忆化搜索, dp[pos][pre][have] 表示 pos处,前一位为pre, 当前有have个满足条件的状态。

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; long long dp[][][];
int n, digit[]; long long dfs(int pos, int pre, int have, int doing)
{
if (pos == -) {
return have;
}
if (!doing && dp[pos][pre][have] != -) {
return dp[pos][pre][have];
}
int end = doing ? digit[pos] : ;
long long ans = ;
for (int i = ; i <= end; i++) {
int nhave = have;
if (pre == && i == ) {
nhave++;
}
ans += dfs(pos - , i, nhave, i == end && doing);
}
if (!doing) {
dp[pos][pre][have] = ans;
}
return ans;
} long long Solve(int n)
{
int pos = ;
while (n) {
digit[pos] = n % ;
n /= ;
pos++;
}
return dfs(pos - , , , );
} int main()
{
memset(dp, -, sizeof(dp));
int _case, t = ;
scanf("%d", &_case);
while (_case--) {
scanf("%d", &n);
printf("Case %d: %lld\n", t++, Solve(n));
}
return ;
}