HDU5787 K-wolf Number

題目連接: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 long
LL 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));
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章