码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 5787 K-wolf Number

时间:2016-08-03 23:47:39      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:

题目:K-wolf Number

链接:http://acm.hdu.edu.cn/showproblem.php?pid=5787

题意:给出L,R,K,求L到R之间有多少数满足:(10进制下)任意两个相等的数字至少相差K位。(1<=L<=R<=1e18,2<=k<=5)。

思路:

  dp[i][j]:表示i 位且前面k位数为j 的情况有多少种,为了细节处理方便,dp数组形式改为:dp[pos][p1][p2][p3][p4]表示pos位,p1、p2、p3、p4是前面四位数字。初始化为10、10、10、10表示前导0。

  采取记忆化搜索的姿势,dfs(pos,p1,p2,p3,p4,flag),flag=1表示这一位数有限制(不是题目要求中的限制,而是比如1234,那么第一位确定为1时,第二位最高只能2的限制。)具体在代码解释。

  有点坑的是我尝试用dp[pos][pre]形式解的时候,第二维不能是1万,应该要10万,不然pre%1000*10+i,原本的1023会变成023i,会被误认为23i,就少判断了一个是否等于0。

AC代码:

 1 #include<stdio.h>
 2 #include<string.h>
 3 typedef long long LL;
 4 LL dp[20][11][11][11][11];
 5 int bt[20],bo;
 6 LL L,R;
 7 int K;
 8 bool check(int p1,int p2,int p3,int p4,int now)  //根据K进行判断i是否可以和p1、p2、p3、p4共存
 9 {
10   if(K==2) return now!=p4;
11   else if(K==3) return now!=p3 && now!=p4;
12   else if(K==4) return now!=p2 && now!=p3 && now!=p4;
13   else return now!=p1 && now!=p2 && now!=p3 && now!=p4;
14 }
15 LL dfs(int pos,int p1,int p2,int p3,int p4,bool flag)
16 {
17   if(pos==-1) return p4!=10;  //结束判断,如果p4还等于10,那说明全是0,在这里,我规定0不满足条件。
18   if(!flag && dp[pos][p1][p2][p3][p4]!=-1) return dp[pos][p1][p2][p3][p4];  //如果以前存过值,直接取。
19   // 存取值都在flag=0的情况下进行,也就是接下来pos位无限制(只有题目限制)的条件下进行。
20   int limit= flag?bt[pos]:9;  //limit表示这一位最高可以取到多少,没有限制就是9,有限制就是原数的这一位数字
21   LL ret=0;
22   for(int i=0;i<=limit;i++)
23   {
24     //如果p4还等于10表示前面全是前导0,i又取0,那么pos位还是前导0。
25     if(i==0 && p4==10) ret+=dfs(pos-1,p1,p2,p3,10,flag && i==limit);
26     else if(check(p1,p2,p3,p4,i)) ret+=dfs(pos-1,p2,p3,p4,i,flag && i==limit); //判断i是否可以和前面的数字共存。
27   }
28   if(!flag) dp[pos][p1][p2][p3][p4]=ret; //存值
29   return ret;
30 }
31 LL solve(LL x)
32 {
33   if(x<=0) return 0;
34   bo=0;
35   while(x)
36   {
37     bt[bo++]=x%10;
38     x/=10;
39   }
40   return dfs(bo-1,10,10,10,10,1);
41 }
42 int main()
43 {
44   while(scanf("%I64d%I64d%d",&L,&R,&K)!=EOF)
45   {
46     memset(dp,-1,sizeof(dp));
47     printf("%I64d\n",solve(R)-solve(L-1));
48   }
49   return 0;
50 }

 

HDU 5787 K-wolf Number

标签:

原文地址:http://www.cnblogs.com/hchlqlz-oj-mrj/p/5734961.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!