bestcoder #56 div 2 B Clarke and problem(dp)

Clarke and problem

 
 Accepts: 169
 
 Submissions: 372
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
克拉克是一名人格分裂患者。某一天,克拉克分裂成了一个学生,在做题。 
突然一道难题难到了克拉克,这道题是这样的:  
给你nn个数,要求选一些数(可以不选),把它们加起来,使得和恰好是pp的倍数(00也是pp的倍数),求方案数。  
对于nn很小的时候,克拉克是能轻易找到的。然而对于nn很大的时候,克拉克没有办法了,所以来求助于你。  
输入描述
第一行一个整数T(1 \le T \le 10)T(1T10),表示数据的组数。  
每组数据第一行是两个正整数n, p(1 \le n, p \le 1000)n,p(1n,p1000)。  
接下来的一行有nn个整数a_i(|a_i| \le 10^9)ai​​(ai​​109​​),表示第ii个数。
输出描述
对于每组数据,输出一个整数,表示问题的方案数,由于答案很大,所以求出对10^9+7109​​+7的答案即可。  
输入样例
1
2 3
1 2
输出样例
2
Hint
有两种方案:什么也不选;全都选。



果然dp還是弱項啊啊啊啊..
不過比最開始的完全無從下手強了不少應該...

至少dp狀態表示相對了....轉移方程沒想出來嗚嗚嗚

官方題解:设d(i, j)d(i,j)表示前ii个数,模pp为jj的方案数,则容易得到d(0, 0)=1, d(i, j)=d(i-1, j)+\sum_{j=0}^{p-1} d(i-1, (j-a[i]) \ mod \ p)d(0,0)=1,d(i,j)=d(i1,j)+j=0p1​​d(i1,(ja[i]) mod p),很多人没1a是因为没注意|a_i| \le 10^9ai​​109​​
 1 /*************************************************************************
 2     > File Name: code/bc/#56/1002.cpp
 3     > Author: 111qqz
 4     > Email: rkz2013@126.com 
 5     > Created Time: 2015年09月22日 星期二 10时47分20秒
 6  ************************************************************************/
 7 
 8 #include<iostream>
 9 #include<iomanip>
10 #include<cstdio>
11 #include<algorithm>
12 #include<cmath>
13 #include<cstring>
14 #include<string>
15 #include<map>
16 #include<set>
17 #include<queue>
18 #include<vector>
19 #include<stack>
20 #include<cctype>
21 #define y1 hust111qqz
22 #define yn hez111qqz
23 #define j1 cute111qqz
24 #define ms(a,x) memset(a,x,sizeof(a))
25 #define lr dying111qqz
26 using namespace std;
27 #define For(i, n) for (int i=0;i<int(n);++i)  
28 typedef long long LL;
29 typedef double DB;
30 const int inf = 0x3f3f3f3f;
31 const int N = 1E3+5;
32 const int MOD = 1E9+7;
33 LL a[N],dp[N][N];
34 int n,p;
35 int main()
36 {
37   #ifndef  ONLINE_JUDGE 
38    freopen("in.txt","r",stdin);
39   #endif
40    int T;
41    cin>>T;
42    while (T--)
43     {
44     scanf("%d %d",&n,&p);
45     for ( int i = 1 ; i <= n ; i++) scanf("%lld",&a[i]);
46     ms(dp,0);
47     dp[0][0] = 1;
48 
49     for ( int i  = 1 ; i <= n ; i++)
50     {
51         for ( int j = 0 ; j < p ; j ++)
52         dp[i][j] = dp[i-1][j];
53     
54 
55     for ( int j = 0 ; j < p ; j++)
56         dp[i][((j+a[i])%p+p)%p] +=dp[i-1][j];
57     for ( int j = 0 ; j < p ; j++)
58         dp[i][j]%=MOD;
59     }
60     printf("%lld\n",dp[n][0]);
61     }
62   
63    
64  #ifndef ONLINE_JUDGE  
65   fclose(stdin);
66   #endif
67     return 0;
68 }
View Code

 

 
posted @ 2015-09-22 11:02  111qqz  阅读(147)  评论(0编辑  收藏  举报