您的位置:首页 > 其它

hdu-5787-K-wolf Number-数位DP

2016-08-03 23:49 337 查看
题意:L到R闭区间中,有多少个数满足连续K位不相等

思路:典型的数位DP

#include<bits/stdc++.h>
using namespace std;
long long dp[20][15][15][15][15];//num,p1,p2,p3,p4
//num当前枚举的位数,p1到p4当前位置前四个状态
//只有flag为0时的值才被记忆话搜索
int dit[20];
int k;
bool pan(int a,int b,int c,int d,int cur) {
if(k==2) return d!=cur;
if(k==3) return (d!=cur)&&(c!=cur);
if(k==4) return (d!=cur)&&(c!=cur)&&(b!=cur);
if(k==5) return (d!=cur)&&(c!=cur)&&(b!=cur)&&(a!=cur);
}
long long dfs(int pos,int p1,int p2,int p3,int p4,bool flag) {
//flag 表示前面的高位是不是全取最大
if(pos==0) { ///枚举到最后一位,如果不是前面全是0的话就返回1
return p4!=10;
}
if(!flag&&dp[pos][p1][p2][p3][p4]!=-1) return dp[pos][p1][p2][p3][p4];
//记忆话搜索
int MAX=flag?dit[pos]:9;
//如果前面全是最大值,最大能取到的就是当前位子的数
long long ans=0;
for(int i=0;i<=MAX;i++) {
if(i==0&&p4==10) ans+=dfs(pos-1,10,10,10,10,flag&&i==MAX);
//前面全是0
else {
if(pan(p1,p2,p3,p4,i))
ans+=dfs(pos-1,p2,p3,p4,i,flag&&i==MAX);
}
}
if(!flag) {
dp[pos][p1][p2][p3][p4]=ans;
}
return ans;
}
long long sov(long long num) {
int len=0;
while(num) {
dit[++len]=num%10;
num/=10;
}
return dfs(len,10,10,10,10,1);
}
int main()
{
long long l,r;
while(scanf("%lld%lld%d",&l,&r,&k)!=EOF) {
memset(dp,-1,sizeof dp);
printf("%lld\n",sov(r)-sov(l-1));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数位DP