Light oj 1125 - Divisible Group Sums (dp)

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1125

题意:

        给你n个数,q次询问,每次询问问你取其中m个数是d的整数倍的方案数。

题意:

        dp[i][j][k] 表示前i个数, %d=j, 取了k个的方案数。

IDSUBMISSION TIMEPROBLEMSOURCECPUMEMORYVERDICT
839200 2016-10-15 14:59:00 1125 - Divisible Group Sums C++ 0.012 1688
Accepted
839186 2016-10-15 14:35:08 1125 - Divisible Group Sums C++ 0.336 1688
Accepted

没优化前 0.336:

 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 typedef long long LL;
 5 const int N = 205;
 6 LL dp[205][25][15]; //dp[i][j][k]表示包含i
 7 int a[N], b[N];
 8 
 9 void solve(int n, int m, int d) {
10     memset(dp, 0, sizeof(dp));
11     for(int i = 1; i <= n; ++i) {
12         dp[i][b[i]][1] = 1;
13         for(int j = 1; j < i; ++j) {
14             for(int x = 0; x < d; ++x) {
15                 for(int y = 2; y <= m; ++y) {
16                     dp[i][(b[i] + x) % d][y] += dp[j][x][y - 1];
17                 }
18             }
19         }
20     }
21 }
22 
23 int main()
24 {
25     int t, n, q;
26     scanf("%d", &t);
27     for(int ca = 1; ca <= t; ++ca) {
28         scanf("%d %d", &n, &q);
29         for(int i = 1; i <= n; ++i) {
30             scanf("%d", a + i);
31         }
32         printf("Case %d:\n", ca);
33         while(q--) {
34             int d, m;
35             scanf("%d %d", &d, &m);
36             for(int i = 1; i <= n; ++i) {
37                 b[i] = (a[i] % d + d) % d;
38             }
39             solve(n, m, d);
40             LL ans = 0;
41             for(int i = 1; i <= n; ++i) {
42                 ans += dp[i][0][m];
43             }
44             printf("%lld\n", ans);
45         }
46     }
47     return 0;
48 }

优化后 0.012:

 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 typedef long long LL;
 5 const int N = 205;
 6 LL dp[205][25][15]; //dp[i][j][k]表示前i个
 7 int a[N], b[N];
 8 
 9 void solve(int n, int m, int d) {
10     memset(dp, 0, sizeof(dp));
11     for(int i = 1; i <= n; ++i) {
12         dp[i][b[i]][1] = 1;
13         for(int j = 0; j < d; ++j) {
14             for(int x = 1; x <= m; ++x) {
15                 dp[i][(b[i] + j) % d][x] += dp[i - 1][j][x - 1];
16                 dp[i][j][x] += dp[i - 1][j][x];
17             }
18         }
19     }
20 }
21 
22 int main()
23 {
24     int t, n, q;
25     scanf("%d", &t);
26     for(int ca = 1; ca <= t; ++ca) {
27         scanf("%d %d", &n, &q);
28         for(int i = 1; i <= n; ++i) {
29             scanf("%d", a + i);
30         }
31         printf("Case %d:\n", ca);
32         while(q--) {
33             int d, m;
34             scanf("%d %d", &d, &m);
35             for(int i = 1; i <= n; ++i) {
36                 b[i] = (a[i] % d + d) % d;
37             }
38             solve(n, m, d);
39             printf("%lld\n", dp[n][0][m]);
40         }
41     }
42     return 0;
43 }

 

posted @ 2016-10-15 17:01  Recoder  阅读(328)  评论(0编辑  收藏  举报