HDU 2089 不要62(数位DP)

来源:互联网 发布:mysql中timestamp 编辑:程序博客网 时间:2024/05/18 11:48

HDU 2089 不要62(数位DP)

http://acm.hdu.edu.cn/showproblem.php?pid=2089

题意:给你两个数n和m,要你求出区间[n,m]间的所有不含4且不含62的数的总数.

分析:本题直接数位DP,对于十进制数一位一位递推即可.(当然本题也可以暴力过).详见<<初探数位DP>> lazycal 论文.

AC代码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int f[15][10];//f[i][j]表示长为i的数,最高位为j时有多少个不含4和62的数int digit[15];//digit中存的数是逆序的且从1开始存到长len,比如9600,存在digit中是0069int len;void init(){    memset(f,0,sizeof(f));    f[0][0]=1;    for(int i=1;i<=10;i++)        for(int j=0;j<=9;j++)if(j!=4)            for(int k=0;k<=9;k++)if(!(j==6&&k==2))                f[i][j] += f[i-1][k];}int cal(int n)//逆序排列存入digit[1...len]中{    int len=0;    while(n)    {        digit[++len]=n%10;        n/=10;    }    digit[len+1]=0;//这句话不加就是wrong,WA了我半天了,我擦    if(len==0) return 1;    int ans=0;    int i;    for(i=len;i>=1;i--)    {        for(int j=0;j<digit[i];j++)if(j!=4 && !(digit[i+1]==6 && j==2))            ans += f[i][j];        if(digit[i]==4 || ( digit[i+1]==6 && digit[i]==2 ))//已经出现了4或62了            break;    }    if(i==0) ans++;//初始数本身是否合格    return ans;}int main(){    int n,m;    init();    while(scanf("%d %d",&n,&m)==2)    {        if(n==0 && m==0)            break;        n--;        int ans=0;        if(n>=0) ans-=cal(n);        ans+=cal(m);        printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击