HDU

来源:互联网 发布:淘宝安卓平板电脑 编辑:程序博客网 时间:2024/06/08 15:33

题目链接


题意:


找出区间[L,R]中有多少个数满足任意相邻的K位均不不相同.


思路:

   观察到k最大为5,所以我们可以考虑在dfs过程中枚举判断连续的k位是否满足条件,dp[pos][pre] 表示的是当前第pos位,前面k位的值为pre时的种数.

     但是在这个过程中需要注意很多细节,比如前导0,还有不满足k位的数也算.

   

#include<bits/stdc++.h>using namespace std;typedef long long ll;const int mod=1e9+7;const int maxn=1e5+10;ll dp[20][maxn];int bit[20];int fac[6];ll l,r,k;void init(){fac[0] = 1;for(int i = 1;i < 6;i++)fac[i] = fac[i-1]*10;return ;}ll dfs(int pos,int pre,int len,int lead,int flag){if(pos < 0) return 1;if(!flag && len == k-1 && lead && dp[pos][pre] != -1)return dp[pos][pre];int up = flag ? bit[pos] : 9;ll res = 0;for(int i = 0;i <= up;i++){if(i || lead){int ok = 1;int tmp = pre;for(int j = 0;j < len;j++){int d = tmp%10;if(d == i){ok = 0;break;}tmp /= 10;}if(!ok) continue;if(len < k -1) res += dfs(pos-1,pre*10+i,len+1,1,i==up&&flag);elseres += dfs(pos-1,(pre*10+i)%fac[k-1],len,1,i==up&&flag);}elseres += dfs(pos-1,0,len,lead,i==up&&flag);}if(!flag && len == k - 1)//由于flag为1的状态不多,为0的状态很多,所以记忆化的时候记忆flag为0的状态 dp[pos][pre] = res;return res;}ll solve(ll x){int len = 0;while(x){bit[len++]=x%10;x/=10;}return dfs(len-1,0,0,0,1);}int main(){init();while(cin>>l>>r>>k){memset(dp,-1,sizeof dp);ll res=solve(r)-solve(l-1);printf("%lld\n",res);}return 0;}/*1 1 220 100 5*/

原创粉丝点击