10616 - Divisible Group Sums
Time limit: 3.000 seconds
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=115&page=show_problem&problem=1557
思路:用DFS+記憶化搜尋枚舉組合,注意數字有<0的。
return dp[i][cnt][sum] = f(i + 1, cnt + 1, ((sum + arr[i]) % d + d) % d) + f(i + 1, cnt, sum);///i<n,cnt<m
完整代碼:
/*0.055s*/
#include<cstdio>
#include<cstring>
typedef long long ll;
ll dp[205][15][25];
int d, m, n, arr[205];
ll f(int i, int cnt, ll sum)
{
if (cnt == m) return dp[i][cnt][sum] = (sum % d ? 0 : 1);///選m個
if (i == n) return dp[i][cnt][sum] = 0;///總共n個,如果i==n,說明cnt!=m,也就是還沒有選完,此時dp=0
if (dp[i][cnt][sum] >= 0) return dp[i][cnt][sum];
return dp[i][cnt][sum] = f(i + 1, cnt + 1, ((sum + arr[i]) % d + d) % d) + f(i + 1, cnt, sum);
}
int main()
{
int cas = 0, q, i, ans;
while (scanf("%d%d", &n, &q), n)
{
for (i = 0; i < n; ++i) scanf("%d", &arr[i]);
printf("SET %d:\n", ++cas);
for (i = 1; i <= q; ++i)
{
ans = 0;
memset(dp, -1, sizeof(dp));
scanf("%d%d", &d, &m);
printf("QUERY %d: %d\n", i, f(0, 0, 0));
}
}
return 0;
}