题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5787
题意:找出区间[L,R]内连续k位数字不同的数的个数。
题解:都是套路的数位dp,因为k<=5,所以直接用一个五位数来存状态即可。
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=100000+5;
ll L,R;
int k;
ll dp[20][maxn];
int mod;
int bit[20];
ll dfs(int len,int pre,bool limit,int c)
{
if(len==0) return 1LL;
if(!limit&&dp[len][pre]!=-1) return dp[len][pre];
int end=limit?bit[len]:9;
ll ret=0;
for(int i=0;i<=end;i++)
{
int tt = pre,flag = 1,tc = c;
while(tt){
tc --;
if(tc == 0) break;
if(i == tt%10) flag = 0;
tt /= 10;
}
if(flag) ret+=dfs(len-1,(pre*10+i)%mod,limit&&(i==end),min(c+1,k));
}
if(!limit)
dp[len][pre]=ret;
return ret;
}
int main()
{
while(~scanf("%I64d%I64d%d",&L,&R,&k))
{
memset(dp,-1,sizeof(dp));
L--;
mod=1;
for(int i=0;i<k;i++)
mod*=10;
int i;
for(i=1;R;i++,R/=10)
bit[i]=R%10;
ll ans=dfs(i-1,0,true,1);
for(i=1;L;i++,L/=10)
bit[i]=L%10;
printf("%I64d
",ans-dfs(i-1,0,true,1));
}
return 0;
}