hdu 5464 Clarke and problem(dp)

Problem Description

Clarke is a patient with multiple personality disorder. One day, Clarke turned into a student and read a book.
Suddenly, a difficult problem appears:
You are given a sequence of number a1,a2,...,an and a number p. Count the number of the way to choose some of number(choose none of them is also a solution) from the sequence that sum of the numbers is a multiple of p(0 is also count as a multiple of p). Since the answer is very large, you only need to output the answer modulo 109+7

Input

The first line contains one integer T(1≤T≤10) - the number of test cases.
T test cases follow.
The first line contains two positive integers n,p(1≤n,p≤1000)
The second line contains n integers a1,a2,...an(|ai|≤109).

Output

For each testcase print a integer, the answer.

Sample Input

1
2 3
1 2

Sample Output

2

 Hint:
2 choice: choose none and choose all.

Source

BestCoder Round #56 (div.2)

附上中文题目:

克拉克是一名人格分裂患者。某一天,有两个克拉克(aaa和bbb)在玩一个方格游戏。
这个方格是一个n∗mn*mn∗m的矩阵,每个格子里有一个数ci,jc_{i, j}c?i,j??。
aaa想开挂,想知道如何打败bbb。
他们要玩qqq次游戏,每一次做一次操作:
1. 取出当中的一个子矩阵(x1,y1)−(x2,y2)(x_1, y_1)-(x_2, y_2)(x?1??,y?1??)−(x?2??,y?2??)玩游戏。两个人轮流行动,每一次只能从这个子矩阵中的一个方格ci,jc_{i, j}c?i,j??中减掉一个的数d(1≤d≤ci,j)d(1 \le d \le c_{i, j})d(1≤d≤c?i,j??),当一个格子的数为000时则不能减。如果操作完后另一者无法操作,那么胜利。否则失败。现在aaa作为先手,想知道是否存在一种方案使得自己胜利。
2. 将ci,jc_{i, j}c?i,j??的数改成bbb  

设d(i,j)表示前i个数,模p为j的方案数,则容易得到  d(0,0)=1;

状态转移:dp[i][j]+=dp[i-1][j];   dp[i][(j+a[i])%p]+=(dp[i-1][j]);

最后的答案为 dp[n][0]

 1 #pragma comment(linker, "/STACK:1024000000,1024000000")
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<math.h>
 7 #include<algorithm>
 8 #include<queue>
 9 #include<set>
10 #include<bitset>
11 #include<map>
12 #include<vector>
13 #include<stdlib.h>
14 #include <stack>
15 using namespace std;
16 int dirx[]={0,0,-1,1};
17 int diry[]={-1,1,0,0};
18 #define PI acos(-1.0)
19 #define max(a,b) (a) > (b) ? (a) : (b)
20 #define min(a,b) (a) < (b) ? (a) : (b)
21 #define ll long long
22 #define eps 1e-10
23 #define MOD 1000000007
24 #define N 1006
25 #define inf 1e12
26 int n,p;
27 int a[N];
28 int dp[N][N];
29 int main()
30 {
31     int t;
32     scanf("%d",&t);
33     while(t--){
34         scanf("%d%d",&n,&p);
35         for(int i=1;i<=n;i++){
36             scanf("%d",&a[i]);
37             a[i]=(a[i]%p+p)%p;
38         }
39
40         memset(dp,0,sizeof(dp));
41         dp[0][0]=1;
42         for(int i=1;i<=n;i++){
43             for(int j=0;j<p;j++){
44                 dp[i][j]+=dp[i-1][j];
45                 dp[i][j]%=MOD;
46
47                 dp[i][(j+a[i])%p]+=(dp[i-1][j]);
48                 dp[i][(j+a[i])%p]%=MOD;
49             }
50         }
51
52         printf("%d\n",dp[n][0]);
53
54     }
55     return 0;
56 }

时间: 2024-10-27 01:56:08

hdu 5464 Clarke and problem(dp)的相关文章

HDU 5464 Clarke and problem 动态规划

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5464 Clarke and problem Accepts: 130 Submissions: 781 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 克拉克是一名人格分裂患者.某一天,克拉克分裂成了一个学生,在做题. 突然一道难题难到了克拉克,这道题是这样的: 给你nn个数

HDU 5464 ( Clarke and problem ) (dp)

dp[i][j] := 前i个数和为j的情况(mod p) dp[i][j] 分两种情况 1.不选取第i个数 -> dp[i][j] = dp[i-1][j] 2.   选取第i个数 -> dp[i][j] = dp[i-1][t] ((t+a[i])%p==j) (为什么很简单的题,思路也有了,比赛的时候就是写不对呢?) #include <iostream> #include <cstdio> #include <cstring> using names

hdu 5464 Clarke and problem

题意:有n个数,a_0, a_1, ... a_(n-1),从中选取一部分数(可以一个都不选),使得其和为p的倍数,问方案数. 解:这题怎么说呢...就差在把背包这俩字甩我脸上了...but,昨天还是没有做出来.-_-! #include <iostream> #include <algorithm> #include <string> #include <cstdio> #include <cstdlib> #include <cstri

HDU 5629 Clarke and tree dp+prufer序列

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=562 题意: 求给每个节点的度数允许的最大值,让你求k个节点能组成的不同的生成树个数. 题解: 对于n个节点形成的一颗生成树,有一个与之唯一对应的大小为n-2的prufer数列. 并且一个节点的度数减一为它出现在prufer数列中的次数. 那么我们求生成树的个数可以转化为求prufer数列的可重集排列,而这个可以用dp来做. dp[i][j][k]表示处理到第i个节点,已经用了j个节点,且可重集大小

hdu 5293 Tree chain problem(树链剖分+树形dp)

题目链接:hdu 5293 Tree chain problem 维护dp[u], sum[u],dp[u]表示以u为根节点的子树的最优值.sum[u]表示以u节点的所有子节点的dp[v]之和.对于边a,b,w,在LCA(a,b)节点的时候进行考虑.dp[u] = min{dp[u], Sum(a,b) - Dp(a,b) + sum[u] | (ab链上的点,不包括u } #pragma comment(linker, "/STACK:1024000000,1024000000")

hdu 2993 MAX Average Problem (斜率优化dp入门)

MAX Average Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5855    Accepted Submission(s): 1456 Problem Description Consider a simple sequence which only contains positive integers as

HDU 5464Clarke and problem(DP)

Clarke and problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 289    Accepted Submission(s): 131 Problem Description Clarke is a patient with multiple personality disorder. One day, Clarke

hdu 2993 MAX Average Problem(斜率DP入门题)

题目链接:hdu 2993 MAX Average Problem 题意: 给一个长度为 n 的序列,找出长度 >= k 的平均值最大的连续子序列. 题解: 这题是论文的原题,请参照2004集训队论文<周源--浅谈数形结合思想在信息学竞赛中的应用> 这题输入有点大,要加读入优化才能过. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 5

BestCoder Round #56 1002 Clarke and problem 1003 Clarke and puzzle

今天第二次做BC,不习惯hdu的oj,CE过2次... 1002 Clarke and problem #include<cstdio> #include<iostream> #include<string> #include<cstring> #include<queue> #include<vector> #include<stack> #include<vector> #include<map>