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 namespace std;
typedef long long ll;
ll a[1005];
ll dp[1005][1005];
const ll MOD = 1000000007;
int main()
{
int t, n, p;
scanf("%d", &t);
while (t--) {
memset(dp, 0, sizeof dp);
scanf("%d%d", &n, &p);
for (int i = 1; i <= n; ++i) {
scanf("%I64d", &a[i]);
}
dp[0][0] = 1;
for (int i = 1; i <= n; ++i) {
for (int j = 0; j < p; ++j) {
int temp = (j - (a[i] % p) + p) % p;
dp[i][j] = (dp[i - 1][temp] + dp[i - 1][j]) % MOD;
}
}
printf("%I64d\n", dp[n][0]);
}
return 0;
}
/**
Input:
78
4 2
1 2 3 4
Output:
8
*/
HDU 5464 ( Clarke and problem ) (dp)
原文:http://www.cnblogs.com/wenruo/p/4830201.html