HDU:2089 不要62

数位dp。学习了这篇PPT。

http://wenku.baidu.com/link?url=mUxdsYomenU-e9SFVPacVtXysemiQA4KnP1EldVuYaB8ECiaLQN4VIAEc19MmHQWQeFqUrU4oFpsX2J1LvrAeoJyAmDYdwMODM8mm3ph327

注意是右边是开区间。用到了区间的分解,说得很详细。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#define ll long long
#define INF 200000000
#define MOD 20071027
#define MAXN 1000005
using namespace std;
int dp[10][10];
int digit[10];
void Init()
{
    dp[0][0]=1;
    for(int i=1; i<=7; ++i)
        for(int j=0; j<=9; ++j)
        {
            for(int k=0; k<=9; ++k)
                if(j!=4&&(!(j==6&&k==2)))dp[i][j]=dp[i][j]+dp[i-1][k];
        }
}
int Set(int val)
{
    int l=0;
    memset(digit,0,sizeof(digit));
    if(val<=0) return 0;
    while(val)
    {
        digit[++l]=val%10;
        val=val/10;
    }
    return l;
}
int solve(int val)
{
    int res=0,len=Set(val);
    for(int i=len; i>=1; --i)
    {
        for(int j=0; j<digit[i]; ++j)
            if(j!=4&&(!(digit[i+1]==6&&j==2)))
                res+=dp[i][j];
        if(digit[i]==4||(digit[i+1]==6&&digit[i]==2))
            break;
    }
    return res;
}
int main()
{
    int n,m;
    Init();
    while(scanf("%d%d",&n,&m))
    {
        if(!n&&!m) break;
        int ans=solve(m+1)-solve(n);
        printf("%d\n",ans);
    }
    return 0;
}


 

你可能感兴趣的:(动态规划,数位dp)