Matches Puzzle Game

Problem Description
As an exciting puzzle game for kids and girlfriends, the Matches Puzzle Game asks the player to find the number of possible equations A−B=C with exactly n (5≤n≤500) matches (or sticks).

In these equations, A,B and C are positive integers. The equality sign needs two matches and the sign of subtraction needs just one. Leading zeros are not allowed.

Please answer the number, modulo a given integer m (3≤m≤2×109).
Input
The input contains several test cases. The first line of the input is a single integer t which is the number of test cases. Then t (1≤t≤30) test cases follow.

Each test case contains one line with two integers n (5≤n≤500) and m (3≤m≤2×109).

Output
For each test case, you should output the answer modulo m.
Sample Input
4
12 1000000007
17 1000000007
20 1000000007
147 1000000007
Sample Output
Case #1: 1
Case #2: 5
Case #3: 38
Case #4: 815630825
Source
 
 
【题意】
  有n根火柴(n<=500),要刚好用完,摆出一个减式A-B=C(A>0,B>0,C>0)求有多少种方案
 
【分析】
  这题很好想,但是就看个人DP能力了,我一开始打的DP就TLE,真是太年轻!
  之前做的几题数位DP都是数字限制,即数值固定一个区间,而现在这题可不管你那个数有多大,只要火柴够用就好了。
  所以之前的题我是记录位数,标记前导0的,再加个越限标记flag。
  搞到我这题一开始就也记录位数了,然记录位数并无卵用!!还会TLE啊ORZ,
  我一开始想法,先减掉3根火柴,减法变加法(加法好打一些),f[i][j][k]表示i位,j根火柴,k表示状态(即两个加数分别是否还处于前导0中),然后记忆化搜索
  位数不超过n/4的,所以时间大概是150*500*4*10*10*2,代码也放一下,正确性还是保证的:
  

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. #include<queue>
  7. #include<cmath>
  8. using namespace std;
  9. #define LL long long
  10.  
  11. int f[][][][];//weishu huocai zero shifoujinwei
  12. // 0 00 1 0x 2 x0 3 xx
  13. int us[]={,,,,,,,,,};
  14. int m,sum;
  15.  
  16. int ffind(int n,int k,int zero,int step)
  17. {
  18. sum++;
  19. if(k<) return ;
  20. if(n==) return (k==&&step==);
  21. if(f[n][k][zero][step]!=-) return f[n][k][zero][step];
  22. LL ans=;
  23. for(int a=;a<;a++)
  24. for(int b=;b<;b++)
  25. {
  26. for(int l=;l<;l++) //xia yi bu shi fou jin wei
  27. {
  28. if(n==&&a==&&zero<=) continue;
  29. if(n==&&b==&&zero!=&&zero!=) continue;
  30. if(step&&(a+b+l<)) continue;
  31. if(!step&&(a+b+l>=)) continue;
  32. int now=;
  33. if(a!=||zero==||zero==) now+=us[a];
  34. if(b!=||zero==||zero==) now+=us[b];
  35. if(a!=||b!=||l!=||zero!=) now+=us[(a+b+l)%];
  36. if(now>k) continue;
  37.  
  38. int nz;
  39. if(a==&&b==&&zero==) nz=;
  40. else if(a==&&zero!=&&zero!=) nz=;
  41. else if(b==&&zero!=&&zero!=) nz=;
  42. else nz=;
  43. ans=(ans+ffind(n-,k-now,nz,l) )%m;
  44. }
  45. }
  46. f[n][k][zero][step]=(int)ans;
  47. return (int)ans;
  48. }
  49.  
  50. int main()
  51. {
  52. int T,kase=;
  53. scanf("%d",&T);
  54. while(T--)
  55. {
  56. sum=;
  57. int n;
  58. scanf("%d%d",&n,&m);
  59. memset(f,-,sizeof(f));
  60. printf("Case #%d: %d\n",++kase,ffind(n/,n,,));
  61. }
  62. return ;
  63. }

TLE的代码

  其实与位数无关,但是不及记录位数就要从低位开始填数了,不然无法表示,会重复。

f[j][k]表示j根火柴,k状态,状态表示当前两个加数分别是否结束了,结束了只能填0,并且不花费火柴。

AC代码如下:

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. #include<queue>
  7. #include<cmath>
  8. using namespace std;
  9. #define LL long long
  10.  
  11. int f[][][];//weishu huocai zero shifoujinwei
  12. // 0 00 1 0x 2 x0 3 xx
  13. int us[]={,,,,,,,,,};
  14. int m;
  15.  
  16. int ffind(int k,int zero,int step)
  17. {
  18. if(k<) return ;
  19. if(zero==)
  20. {
  21. if(step==) k-=;
  22. return k==;
  23. }
  24. if(f[k][zero][step]!=-) return f[k][zero][step];
  25. LL ans=;
  26. for(int a=;a<;a++)
  27. {
  28. for(int b=;b<;b++)
  29. {
  30. int now=;
  31. if(zero==||zero==) now+=us[a];
  32. if(zero==||zero==) now+=us[b];
  33. now+=us[(a+b+step)%];
  34. if(now>k) continue;
  35.  
  36. ans=(ans+ffind(k-now,zero,a+b+step>=) )%m;
  37. if(a!=&&zero!=&&zero!=) ans=(ans+ffind(k-now,zero==?:,a+b+step>=) )%m;
  38. if(b!=&&zero!=&&zero!=) ans=(ans+ffind(k-now,zero==?:,a+b+step>=) )%m;
  39. if(a!=&&b!=&&zero==) ans=(ans+ffind(k-now,,a+b+step>=) )%m;
  40.  
  41. if(zero==||zero==) break;
  42. }
  43. if(zero==||zero==) break;
  44. }
  45.  
  46. f[k][zero][step]=(int)ans;
  47. return (int)ans;
  48. }
  49.  
  50. int main()
  51. {
  52. int T,kase=;
  53. scanf("%d",&T);
  54. while(T--)
  55. {
  56. int n;
  57. scanf("%d%d",&n,&m);
  58. memset(f,-,sizeof(f));
  59. printf("Case #%d: %d\n",++kase,ffind(n,,));
  60. }
  61. return ;
  62. }

[HDU 5456]

所以如果跟位数无关,最好思想回到原始的位置啊,从低位开始填可能会--柳暗花明又一村??

2016-10-09 14:15:15

【HDU 5456】 Matches Puzzle Game (数位DP)的更多相关文章

  1. HDU5456 Matches Puzzle Game(DP)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5456 Description As an exciting puzzle game for ...

  2. HDU 4507 (鬼畜级别的数位DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4507 题目大意:求指定范围内与7不沾边的所有数的平方和.结果要mod 10^9+7(鬼畜の元凶) 解题 ...

  3. HDU 5787 K-wolf Number (数位DP)

    K-wolf Number 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5787 Description Alice thinks an integ ...

  4. 【HDU 3652】 B-number (数位DP)

    B-number Problem Description A wqb-number, or B-number for short, is a non-negative integer whose de ...

  5. HDU 5787 K-wolf Number(数位DP)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5787 [题目大意] 求区间[L,R]内十进制数相邻k位之间不相同的数字的个数. [题解] 很显然的 ...

  6. 2017"百度之星"程序设计大赛 - 复赛1005&&HDU 6148 Valley Numer【数位dp】

    Valley Numer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  7. HDU 4352 XHXJ's LIS 数位dp lis

    目录 题目链接 题解 代码 题目链接 HDU 4352 XHXJ's LIS 题解 对于lis求的过程 对一个数列,都可以用nlogn的方法来的到它的一个可行lis 对这个logn的方法求解lis时用 ...

  8. HDU 2089 不要62(数位dp模板题)

    http://acm.hdu.edu.cn/showproblem.php?pid=2089 题意:求区间内不包含4和连续62的数的个数. 思路: 简单的数位dp模板题.给大家推荐一个好的讲解博客.h ...

  9. hdu 4352 XHXJ's LIS 数位dp+状态压缩

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4352 XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others ...

  10. HDU 2089(暴力和数位dp)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=2089 不要62 Time Limit: 1000/1000 MS (Java/Others)    M ...

随机推荐

  1. msql 按值排序

    ORDER BY find_in_set(status,'705,710,706,1027,707,709,708'),create_time desc

  2. SQL查询数据库表字段值不为空或Null的所有列

    ) set @TableName = 'Agency' -- 表名 declare @querySql nvarchar(max) set @querySql = 'select ' ) declar ...

  3. Java对象与Json之间的转换

    使用Jackson的ObjectMapper对象的readValue和writeValueAsString方法可以进行转换. 对于简单基本类型或String类型的对象,使用上述方法可以满足. 但是如果 ...

  4. html 微信开发——微信授权

    微信JS-SDK说明文档 链接地址:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html 微信web开发:http: ...

  5. Hibernate注解错误之- org.hibernate.MappingException: Could not determine type for:

    Hibernate 注解 @OneToOne 时候,出现以下错误,经调试,发现 注解要么全部放在字段上,要么全部放在get方法上,不能混合使用! org.hibernate.MappingExcept ...

  6. 20160314 Request 和Response

    一.Response 1.Resonse的继承结构: ServletResponse--HttpServletResponse 2.Response代表响应,于是响应消息中的 状态码.响应头.实体内容 ...

  7. jsf taglib定义函数

    创建文件   在文件中添加function标签 <function> <function-name>getFileContent</function-name> & ...

  8. C++编程注意事项

    1.所有成员变量在构造函数中进行初始化操作,如指针赋值为空,bool赋值为FALSE(默认为TRUE); 2.构造函数与析构函数配对出现,执行反向操作,保证执行析构之后,没有遗留问题存在: 3.如果需 ...

  9. Net中exe之间的消息传递

    1.创建一个消息通讯类 using System;using System.Collections.Generic;using System.Linq;using System.Text;using ...

  10. HDU 5351 MZL's Border (规律,大数)

    [HDU 5351 MZL's Border]题意 定义字符串$f_1=b,f_2=a,f_i=f_{i-1}f_{i-2}$. 对$f_n$的长度为$m$的前缀$s$, 求最大的$k$满足$s[1] ...