Test instructions: There are two people Petra and Jan to divide n snacks to eat, everyone to different snacks have different love degree, and then two people first with a coin to decide who the first choice, and then take turns to choose snacks away, Petra each time will choose the current rest of their favorite snacks, If you have the same degree of love to choose the other side more dislike of that, Jan each choice will let oneself finally get all the total satisfaction of snacks, if there are different choices to let their final total satisfaction value the same, will choose to let the other end of the total satisfaction higher.
Finally the total satisfaction of Petra and Jan was output.
The problem: This DP problem thinking is very ingenious, just a long time to think of how to DP, and then see the big God solved the puzzle and admire unceasingly.
First Petra the choice of simple rough, we can first according to her satisfaction from big to small order, she must be in this order to choose snacks, and then in order to let her final total satisfaction, she will see whether Petra next selected snacks will let oneself can not reach the best value (for the N/2 before the maximum If it is, she will have to take away early, then DP of the idea, F[i][j] said the first I snacks selected J to Jan,jan Maximum can let themselves reach the maximum satisfaction value is how much.
Then it is obvious that the former I snacks can be removed (i + 1)/2 snacks (I/2) or a snack (Petra first), then f[i][j] = max (F[i-1][j],f[i-1][j-1] + val2[i]). It is better to choose or not to select. One of the conditions is that if the total value of Jan is the same, she will make the other a higher value, so another DP array is needed, and one sentence in the great God puzzle is very good: you can think of the snack val1 value as the cost, the Val2 value as the value, the goal is to let Jan take the most valuable case, the least cost. So add a cost[i][j], in f[i][j] I snacks not selected case, cost[i][j] = min (Cost[i-1][j], cost[i-1][j-1] + val1[i]).
Finally, you can use a scrolling array to reduce the one-dimensional space, and J to reverse the enumeration.
Finally, the last, good sleepy, can roll to sleep ...
#include <stdio.h>#include <string.h>#include <algorithm>using namespace STD;Const intN =1005;Const intINF =0x3f3f3f3f;structGoo {intV1, v2;} Goo[n];intN, F[n], cost[n];Charfir[Ten];BOOLcmpConstGoo &a,ConstGoo &b) {if(a.v1! = b.v1)returnA.v1 > b.v1;returnA.v2 < B.v2;}intMain () {intTscanf("%d", &t); while(t--) {memset(F,0,sizeof(f));memset(Cost, INF,sizeof(cost));scanf("%d%s", &n, FIR);intsum =0, FF =1, cnt =0; for(inti =1; I <= N; i++) {scanf("%d%d", &GOO[I].V1, &GOO[I].V2); sum + = GOO[I].V1; } Sort (Goo +1, Goo + n +1, CMP);if(fir[0] ==' P ') FF =2; cost[0] =0; for(inti = FF; I <= N; i++) {cnt++;intTemp = (cnt +1) /2; for(intj = temp; J >=1; j--) {if(F[j-1] + goo[i].v2 > F[j]) {F[j] = f[j-1] + goo[i].v2; COST[J] = cost[j-1] + goo[i].v1; }Else if(F[j-1] + Goo[i].v2 = = F[j]) cost[j] = min (cost[j], cost[j-1] + goo[i].v1); } }printf("%d%d\n", sum-cost[(CNT +1) /2], f[(CNT +1) /2]); }return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
UVA 12260 (DP)