Alice and Bob like eating cake very much. One day, Alice and Bob went to a bakery and bought many cakes.
Now we know that they have bought n cakes in the bakery. Both of them like delicious cakes, but they evaluate the cakes as different values. So they decided to divide those cakes by following method.
Alice and Bob do n / 2 steps, at each step, Alice choose 2 cakes, and Bob takes the cake that he evaluates it greater, and Alice take the rest cake.
Now Alice want to know the maximum sum of the value that she can get.
The first line is an integer T which is the number of test cases.
For each test case, the first line is an integer n (1<=n<=800). Note that n is always an even integer.
In following n lines, each line contains two integers a[i] and b[i], where a[i] is the value of ith cake that Alice evaluates, and b[i] is the value of ith cake that Bob evaluates. (1<=a[i], b[i]<=1000000)
Note that a[1], a[2]..., a[n] are n distinct integers and b[1], b[2]..., b[n] are n distinct integers.
For each test case, you need to output the maximum sum of the value that Alice can get in a line.
1 6 1 6 7 10 6 11 12 18 15 5 2 14
28Author: HUA, Yiwei
#include<stdio.h> #include<string.h> #include<map> #include<algorithm> using namespace std; typedef long long ll; #define F first #define S second #define mod 1000000007 const int INF = 1<<30; const int N = 810; int dp[N][N]; pair<int,int> pr[N]; bool cmp(pair<int,int> i, pair<int,int> j) {return i>j;} int main() { int T, n; scanf("%d", &T); while(T--) { scanf("%d", &n); for(int i=1; i<=n; i++) scanf("%d%d", &pr[i].S,&pr[i].F); sort(pr+1,pr+n+1,cmp); //知道递推方程怎么来的就知道为什么要排序了 memset(dp, 0, sizeof(dp)); for(int i=1; i<=n; i++) { for(int j=1; j<=i/2; j++) { dp[i][j] = max(dp[i-1][j],dp[i-1][j-1]+pr[i].S); } } printf("%d\n", dp[n][n/2]); } return 0; }可以看到每层状态都是由上一层状态转移过来的,所以这里可以采用滚动数组减少一维空间,只需重复利用一维来进行操作。可以看到如果是二维的话,转移的过程并不会影响到上一层,而如果是一维的话: dp[j] = max(dp[j],dp[j-1]+...); 这样其实是有点问题的,问题在于更新 j 这个状态时其实是覆盖了相当于二维的上一层的 j 状态,那么在更新 j+1 这个状态时就不是由原来的 j 这个状态转移来的了。所以我们可以将循环的顺序调转一下,这样就不会有所影响了。
#include<stdio.h> #include<string.h> #include<map> #include<algorithm> using namespace std; typedef long long ll; #define F first #define S second #define mod 1000000007 const int INF = 1<<30; const int N = 810; int dp[N]; typedef pair<int,int> pii; pii pr[N]; bool cmp(pii i, pii j) {return i>j;} int main() { int T, n; scanf("%d", &T); while(T--) { scanf("%d", &n); for(int i=1; i<=n; i++) scanf("%d%d", &pr[i].S,&pr[i].F); sort(pr+1,pr+n+1,cmp); memset(dp, 0, sizeof(dp)); for(int i=1; i<=n; i++) { for(int j=i/2; j>=1; j--) { dp[j] = max(dp[j],dp[j-1]+pr[i].S); } } printf("%d\n", dp[n/2]); } return 0; }