大家都是用优雅的记忆化搜索做的,我最笨,懒得写记忆化,直接递推暴力转移了。
这题的难点在贪心上。自己想出来了
有人需要的话我就写详细证明吧。。
1 #include <cstdio>
2 #include <iostream>
3 #include <cstring>
4 #include <algorithm>
5 using namespace std;
6 typedef pair<int, int> P;
7 #define x first
8 #define y second
9 const int MAXN = 50 + 2;
10
11 P v[MAXN];
12 int N, K;
13
14 inline bool cmp(const P &lhs, const P &rhs)
15 {
16 return (double) ((double)lhs.y / (double)lhs.x) >
17 (double) ((double)rhs.y / (double)rhs.x);
18 }
19
20 int f[MAXN][MAXN][MAXN * MAXN];
21
22 int main()
23 {
24 //freopen("12589.in", "r", stdin);
25 int T;
26 cin>>T;
27 int cnt = 0;
28 while(T--)
29 {
30 cnt++;
31 cin>>N>>K;
32 register int a, b;
33 for(int i = 1; i <= N; i++)
34 {
35 scanf(" %d %d", &a, &b);
36 v[i] = P(a, b);
37 }
38
39 sort(v + 1, v + N + 1, cmp);
40
41 memset(f, -0x3f, sizeof(f));
42 for(int i = 0; i <= N; i++)
43 for(int j = 0; j <= K; j++)
44 f[i][j][0] = 0;
45
46 register int mxh[2] = {0}, d = 0;
47 for(int i = 1; i <= N; i++)
48 {
49 d ^= 1;
50 for(int j = 0; j <= min(i, K); j++)
51 for(int h = 0; h <= mxh[d]; h++)
52 {
53 f[i + 1][j + 1][h + v[i].y] = max(f[i + 1][j + 1][h + v[i].y],
54 f[i][j][h] + (v[i].x * v[i].y) + 2 * (v[i].x * h));
55 f[i + 1][j][h] = max(f[i + 1][j][h], f[i][j][h]);
56 mxh[d ^ 1] = max(mxh[d ^ 1], h + v[i].y);
57 }
58 }
59
60 int ans = 0;
61 for(int i = 1; i <= max(mxh[0], mxh[1]); i++)
62 ans = max(ans, f[N + 1][K][i]);
63 printf("Case %d: %d
", cnt, ans);
64 }
65 return 0;
66 }