给你n个数 两个人去取 每个数有两种价值 对应ai和bi 每次去两个数 b那他认为较大的 a那剩下的 问a拿的最大价值是多少
dp【i】【j】表示前i个数 a拿j个的最大价值 很显然会想到 说对于i这种不一定a能拿到啊 其实 仔细想想 除了b认为最大价值对应的那个ai拿不到外 其余的都是和玉拿到的
所以很显然 的然bi排个序 那么第一个就拿不到了 合一用来初始化数组 及dp【1】【0】 = 0;接下来就是转移方程了 对于dp【i】【j】 来说 可以i是可以拿 额可以不拿的 这就有 dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1] + num[i].ai); 这样问题解决了
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; int dp[1010][1010]; struct node { int ai, bi; }num[1010]; int cmp(node a, node b) { return a.bi > b.bi; } int max(int a, int b) { return a > b ? a : b; } int main() { int T, i, j, n; scanf("%d", &T); while(T--) { scanf("%d", &n); for(i = 1; i <= n; i++) scanf("%d%d", &num[i].ai, &num[i].bi); sort(num + 1, num + 1 + n, cmp); memset(dp, 0, sizeof(dp)); dp[1][0] = 0; for(i = 2; i <= n; i++) { for(j = 1; j * 2 <= i; j++) { dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1] + num[i].ai); } } printf("%d\n", dp[n][n/2]); } return 0; }