递推DP HDOJ 5389 Zero Escape

题目传送门

 1 /*
 2     题意:把N个数分成两组,一组加起来是A,一组加起来是B,1<=A,B<=9,也可以全分到同一组。其中加是按照他给的规则加,就是一位一位加,超过一位数了再拆分成一位一位加。
 3     DP:dp[i][j]记录前i个数累加和为j的方案数,那么状态转移方程:dp[i][j+a[i]] += dp[i-1][j]; 当然,dp[i][a[i]] = 1;
 4         然后考虑几种特殊情况:都前往S1门或S2门,方案数+1。另外,比赛时我写出正确的转移方程,结果答案输出dp[n][s1]+dp[n][s2]将近是2倍,没多想,弃之,当时思绪很乱,以为方法错误。。。。
 5 */
 6 /************************************************
 7 * Author        :Running_Time
 8 * Created Time  :2015-8-13 14:39:58
 9 * File Name     :J.cpp
10  ************************************************/
11
12 #include <cstdio>
13 #include <algorithm>
14 #include <iostream>
15 #include <sstream>
16 #include <cstring>
17 #include <cmath>
18 #include <string>
19 #include <vector>
20 #include <queue>
21 #include <deque>
22 #include <stack>
23 #include <list>
24 #include <map>
25 #include <set>
26 #include <bitset>
27 #include <cstdlib>
28 #include <ctime>
29 using namespace std;
30
31 #define lson l, mid, rt << 1
32 #define rson mid + 1, r, rt << 1 | 1
33 typedef long long ll;
34 const int MAXN = 1e5 + 10;
35 const int INF = 0x3f3f3f3f;
36 const int MOD = 258280327;
37 int dp[MAXN][10];
38 int a[MAXN];
39 int n, s1, s2;
40
41 int cal(int x, int y)   {
42     int ret = x + y;
43     ret %= 9;
44     if (ret == 0)   return 9;
45     else    return ret;
46 }
47
48 int main(void)    {     //HDOJ 5389 Zero Escape
49     int T;  scanf ("%d", &T);
50     while (T--) {
51         scanf ("%d%d%d", &n, &s1, &s2);
52         int sum = 0;
53         for (int i=1; i<=n; ++i)    {       //把N个数全加起来再按照规则处理和两个两个加是一样的
54             scanf ("%d", &a[i]);    sum = cal (sum, a[i]);
55         }
56
57         memset (dp, 0, sizeof (dp));
58         for (int i=1; i<=n; ++i)    {
59             dp[i][a[i]] = 1;
60             for (int j=9; j>=0; --j)    {
61                 dp[i][j] = (dp[i][j] + dp[i-1][j]) % MOD;
62                 if (j + a[i] > 9)   {
63                     int x = cal (j, a[i]);
64                     dp[i][x] = (dp[i][x] + dp[i-1][j]) % MOD;
65                 }
66                 else    {
67                     dp[i][j+a[i]] = (dp[i][j+a[i]] + dp[i-1][j]) % MOD;
68                 }
69             }
70         }
71
72         int ans = 0;
73         if (cal (s1, s2) == sum)    {       //两个门都能进去且条件符合
74             ans += dp[n][s1];
75             if (s1 == sum)  ans--;
76         }
77         if (s1 == sum)  ans++;      //可以全进一个门
78         if (s2 == sum)  ans++;
79
80         printf ("%d\n", ans);
81     }
82
83     return 0;
84 }
时间: 2024-10-10 06:09:34

递推DP HDOJ 5389 Zero Escape的相关文章

递推DP HDOJ 5459 Jesus Is Here

题目传送门 题意:简单来说就是sn = sn-1 + sn-2递推而来,求其中所有c字符的:∑i<j:sn[i..i+2]=sn[j..j+2]=‘‘cff"(j−i) mod 530600414 分析:一开始觉得很难下手,类似于斐波那契数列,最后的数字会很大,不能正常求解.想到试试打表找规律,结果并没有找到什么规律...最后也没想出什么来.赛后才恍然大悟,这是递推题,拿来别人的思路: 串长度len,串中字符c的个数num,串中所有字符c的位置之和sum,串中所有字符c之间的距离之和ans

递推DP HDOJ 5092 Seam Carving

题目传送门 1 /* 2 题意:从上到下,找最短路径,并输出路径 3 DP:类似数塔问题,上一行的三个方向更新dp,路径输出是关键 4 */ 5 #include <cstdio> 6 #include <algorithm> 7 #include <iostream> 8 #include <cstring> 9 #include <cmath> 10 #include <string> 11 #include <vector

hdu 1284 钱币兑换问题 (递推 || DP || 母函数)

钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 5069    Accepted Submission(s): 2868 Problem Description 在一个国家仅有1分,2分,3分硬币,将钱N兑换成硬币有很多种兑法.请你编程序计算出共有多少种兑法. Input 每行只有一个正整数N,N小于32768. Outpu

D. Caesar&#39;s Legions 背包Dp 递推DP

http://codeforces.com/problemset/problem/118/D 设dp[i][j][k1][k2] 表示,放了i个1,放了j个2,而且1的连续个数是k1,2的连续个数是k2 如果这样写,用dfs写是很简单的.但是超时,我记忆化不到 如果用递推写,对于每一个状态,更新到下一个状态. 如果放的是1,那么新的状态是dp[i + 1][j][k1 + 1][0]也就是,用多了一个1,而且连续的个数也增加了.同时,2的连续个数就打破了,变成了0 这种枚举旧状态,更新下一个状态

递推DP URAL 1031 Railway Tickets

题目传送门 1 /* 2 简单递推DP:读题烦!在区间内的都更新一遍,dp[]初始化INF 3 注意:s1与s2大小不一定,坑! 4 详细解释:http://blog.csdn.net/kk303/article/details/6847948 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <algorithm> 9 #include <cstring> 10 #include <s

递推DP URAL 1119 Metro

题目传送门 1 /* 2 题意:已知起点(1,1),终点(n,m):从一个点水平或垂直走到相邻的点距离+1,还有k个抄近道的对角线+sqrt (2.0): 3 递推DP:仿照JayYe,处理的很巧妙,学习:) 4 好像还要滚动数组,不会,以后再补 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <algorithm> 9 #include <cmath> 10 #include <cs

Code Force 429B Working out【递推dp】

Summer is coming! It's time for Iahub and Iahubina to work out, as they both want to look hot at the beach. The gym where they go is a matrix a with n lines and mcolumns. Let number a[i][j] represents the calories burned by performing workout at the

递推DP UVA 607 Scheduling Lectures

题目传送门 题意:教授给学生上课,有n个主题,每个主题有ti时间,上课有两个限制:1. 每个主题只能在一节课内讲完,不能分开在多节课:2. 必须按主题顺序讲,不能打乱.一节课L时间,如果提前下课了,按照时间多少,学生会有不满意度.问最少要几节课讲完主题,如果多种方案输出不满意度最小的 分析:dp[i]表示前i个主题最少要多少节课讲完,那么这个主题可能和上个主题在同一节课讲或者多开新的一节课讲,状态转移方程:看代码:优先满足节数少的情况 收获:普通的递推DP 代码: /**************

CodeForces Round#229 DIV2 C 递推DP

对这道题目也只好说呵呵了,没注意k的范围最大才10,所以昨晚纠结了很久,没什么好的方法来处理,后来无奈想去翻翻题解,发现人家开头就来了句,因为k的范围比较小 所以.........我只好暂停马上回头看看题目,是的,k比较小所以完全可以先在询问前预处理DP一遍, DP就比较清晰了,dp[i][j]  (i>=0 && i<k,,,,j>=i && j <=n)代表意义呢 以i为开头的  区间[1,j]注意 是 1~j的 所需要的操作数,题目问的是最小操