HDU 2089 不要62(数位dp)

题目链接: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;
}



你可能感兴趣的:(HDU 2089 不要62(数位dp))