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 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 */