Description
给出多个选手下黑白子的能力,先要从中选出15人下黑子,15人下白子,欲使这30人能力和最大,输出这个最大能力值
Input
一组用例,每行两个整数分别表示一名选手下黑白子的能力,以文件尾结束输入
Output
输出选出的30的能力和最大值
Sample Input
87 84
66 78
86 94
93 87
72 100
78 63
60 91
77 64
77 91
87 73
69 62
80 68
81 83
74 63
86 68
53 80
59 73
68 70
57 94
93 62
74 80
70 72
88 85
75 99
71 66
77 64
81 92
74 57
71 63
82 97
76 56
Sample Output
2506
Solution
三维dp,以dp[i][j][k]表示从前i个人中选j个下黑子k个下白子的最大能力值,以p[i].b和p[i].w表示第i名选手下黑白子的能力,那么轻易得出递推方程
dp[i][j][k]=max(dp[i][j][k],dp[i-1][j-1][k]+p[i].b,dp[i-1][j][k-1]+p[i],w)
答案即为dp[n][15][15],其中n为选手人数
Code
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define maxn 1111
struct node
{
int b,w;
}p[maxn];
int dp[maxn][16][16];
int main()
{
int n=0;
while(~scanf("%d%d",&p[n].b,&p[n].w))n++;
memset(dp,0,sizeof(dp));
dp[0][1][0]=p[0].b,dp[0][0][1]=p[0].w;
for(int i=1;i<n;i++)
for(int j=0;j<16;j++)
for(int k=0;k<16;k++)
{
if(j)dp[i][j][k]=max(dp[i][j][k],max(dp[i-1][j][k],dp[i-1][j-1][k]+p[i].b));
if(k)dp[i][j][k]=max(dp[i][j][k],max(dp[i-1][j][k],dp[i-1][j][k-1]+p[i].w));
}
printf("%d\n",dp[n-1][15][15]);
return 0;
}