题目链接:HDU 2089 不要62
数位dp。
听大神说这是数位dp最基础的题目,学习中。
感觉做这类题目用记忆化搜索比递推来的清晰。
dp[pos][0]表示长度为pos + 1 ,并且第pos + 2 位不是6的符合要求的数的和,dp[pos][1] 表示长度为pos + 1 ,并且第pos + 2 位的数是6的符合要求的数的和。
#include <iostream>
#include <cstring>
using namespace std;
const int MAX_N = 10 + 5;
int dp[MAX_N][2];
int num[MAX_N];
int n,m;
int f(int pos, int st, bool limit)
{
if(pos == -1)
return 1;
if(!limit && dp[pos][st] != -1)
return dp[pos][st];
int ans = 0;
int last = limit ? num[pos] : 9;
for(int i = 0; i <= last; i++)
{
if(i == 4 || (i == 2 && st))
continue;
ans += f(pos - 1, i == 6, limit && i == last);
}
if(!limit)
dp[pos][st] = ans;
return ans;
}
int cal(int n)
{
int pos = 0;
while(n > 0)
{
num[pos] = n % 10;
n /= 10;
pos++;
}
return f(pos - 1, 0, 1);
}
int main()
{
memset(dp, -1, sizeof(dp));
while(cin >> n >> m, n + m)
cout << cal(m) - cal(n - 1)<< endl;
return 0;
}
本文详细介绍了数位dp的基础概念及其在解决HDU2089「不要62」问题上的应用。通过记忆化搜索的方法,清晰地展示了如何利用数位dp技巧求解特定条件下的数的组合问题。
2027

被折叠的 条评论
为什么被折叠?



