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

hdoj 5389 Zero Escape

时间:2015-08-15 17:54:34      阅读:107      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5389

大体题意是:有两个门A和B,还有一群人,每个人都有一个数字,

疯了一样的T。。比赛的时候十连T也是醉醉的。  

这道题感觉像DP,但是不知道从何下手,看别人敲出来才知道怎么去用。

在比赛过程中还有一个问题,想法对了,样例过了,但是T了

原因是因为数组开大了,在dp的过程中用了memset,导致T

在标程里,用了滚动数组,感觉很巧妙,因为dp只需要知道上一状态即可,

利用异或的性质,不断滚动0101010101

---------------------------------------关于digital的性质------------------------------------------------------------

当一群人各位数字之和等于门上数字的时候才可以通过门,可以只通过一个门也可以两个门都通过。

The digital root of a non-negative integer is the single digit value obtained by an iterative process of summing digits,

on each iteration using the result from the previous iteration to compute a digit sum. The process continues until

a single-digit number is reached.

关于digital root(以下用R表示),有以下几条性质:

1、9加(乘)任何数所得的和(积)的数字根,等于原数的数字根(9)

2、若A+B=C,则A,B的数字根(Ra Rb)的和的数字根为C的数字根(Rc)

3、若A*B=C,则A,B的数字根(Ra Rb)的积的数字根为C的数字根(Rc)

4、若A^n=B,则Ra^n的数字跟=Rb。

------------------DP思路---------------------

dp[i+1][a[i]+k] = dp[i+1][a[i]+k] + dp[i][k];

更新加了一个数之后的状态

dp[i+1][k] = dp[i+1][k] + dp[i][k];

加上上一状态的情况数

------------------分情况讨论-------------------

之后比较巧的是对于情况的讨论

1、如果数字跟不等于A+B且不等于A且不等于B,则情况数为0

2、如果是数字根等于A+B的数字根,那么情况数就等于dp[n][A] = dp[n][B]

3、如果数字根等于A或B,那么情况数只有一个

4、如果数字跟等于A且等于B,那么情况数有两个

具体代码如下

1         int ans=dp[now][A]*(((A+B)%9)==sum);
2         if(sum==A&&B!=0)ans=(ans+1)%MOD;
3         if(sum==B&&A!=0)ans=(ans+1)%MOD;

注意到后两种情况其实可以合并,如果A=B的话,后两个if语句同时成立,ans = 2;

 1 #include<stdio.h>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define rep(i,j,k) for(int i=(int)j;i<(int)k;i++)
 5 #define per(i,j,k) for(int i=(int)j;i>(int)k;i--)
 6 using namespace std;
 7 const int MAXN = 1000000;
 8 const int MOD = 258280327;
 9 int T, n;
10 int A, B;
11 int a[MAXN];
12 int now, sum, ans;
13 int dp[2][10];
14 int main(){
15     scanf("%d",&T);
16     while(T--){
17         scanf("%d",&n);
18         scanf("%d %d",&A,&B);
19         A %= 9;B %= 9;
20         sum = 0;
21         rep(i,0,n){
22             scanf("%d",&a[i]);
23             a[i] = a[i] % 9;
24             sum = (sum+a[i])%9;
25         }
26         if( sum != ((A+B)%9) && sum != A && sum != B){
27             puts("0");
28             continue;
29         }
30         memset(dp,0,sizeof(dp));
31         dp[0][0] = 1;
32         now = 0;
33         rep(i,0,n){
34             now ^= 1;
35             rep(k,0,9) dp[now][k] = 0;
36             rep(k,0,9){
37                 dp[now][(a[i]+k)%9] = ( dp[now][(a[i]+k)%9] + dp[now^1][k])%MOD;
38                 dp[now][k] = ( dp[now][k] + dp[now^1][k])%MOD;
39             }
40         }
41         int ans=dp[now][A]*(((A+B)%9)==sum);
42         if(sum==A&&B!=0)ans=(ans+1)%MOD;
43         if(sum==B&&A!=0)ans=(ans+1)%MOD;
44         printf("%d\n",ans);
45     }
46 }

 

hdoj 5389 Zero Escape

标签:

原文地址:http://www.cnblogs.com/blueprintf/p/4732618.html

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