HDU5787 K-wolf Number

来源:互联网 发布:小蜜蜂软件官方网 编辑:程序博客网 时间:2024/06/05 14:18

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5787


【题意】给定三个数i,j,k。问i-j之间有多少任意k位数都不相同的数。


【分析】数位dp,用dp[pos][p1][p2][p3][p4]表示当前位为第pos位,前第一位为p4,前第二位为p3,前第三位为p2,前第四位为p1的数的满足条件的数的个数。用特殊的10表示前导0。用dfs进行记忆化搜索。搜索过程中用flg标记前位是否取满以确定当前位的取值上限。


【代码】

#include<iostream>#include<cstdio>#include<cstring>using namespace std;#define LL long longLL dp[20][12][12][12][12];int dig[20];LL l,r;int k;bool check(int p1,int p2,int p3,int p4,int p5){    if(k==2)        return p5!=p4;    if(k==3)        return (p5!=p4 && p5!=p3);    if(k==4)        return (p5!=p4 && p5!=p3 && p5!=p2);    return (p5!=p4 && p5!=p3 && p5!=p2 && p5!=p1);}LL dfs(int pos,int p1,int p2,int p3,int p4,bool flg){    if(pos==0)        return p4!=10;    if(!flg && dp[pos][p1][p2][p3][p4]!=-1)        return dp[pos][p1][p2][p3][p4];    int ed=flg?dig[pos]:9;    LL ans=0;    for(int i=0;i<=ed;++i){        if(i==0 && p4==10)            ans+=dfs(pos-1,10,10,10,10,flg && i==ed);        else            if(check(p1,p2,p3,p4,i))                ans+=dfs(pos-1,p2,p3,p4,i,flg && i==ed);    }    if(!flg)        dp[pos][p1][p2][p3][p4]=ans;    return ans;}LL cal(LL x){    if(x<=0)        return 0;    LL tmp=x;    int len=0;    while(tmp){        dig[++len]=tmp%10;        tmp/=10;    }    return dfs(len,10,10,10,10,1);}int main(){    while(~scanf("%I64d %I64d %d",&l,&r,&k)){        memset(dp,-1,sizeof(dp));        printf("%I64d\n",cal(r)-cal(l-1));    }}


0 0
原创粉丝点击