HDU 5787 K-wolf Number 2016多校第五场1007 数位dp

题目链接: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\n",ans-dfs(i-1,0,true,1));
	}
	return 0;
}

posted on 2016-08-29 16:26  57老帅了  阅读(147)  评论(0编辑  收藏  举报

导航