题意:每个人都可以派去下黑棋或者下白棋,但不能都下,然后每人都有各自擅长度,最后选出30人,15人下黑棋,15人下白棋,使得下白棋的擅长度加上下黑棋的擅长度之和最大。
题解:dp[i][j]代表i个人下黑棋,j个人下白棋的最大价值,转移方程即为max(dp[i][j],dp[i-1][j]+a,dp[i][j-1]+b),需要注意这是0,1背包,所以要从大往小dp
View Code
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 int dp[20][20]; 6 int main() 7 { 8 memset(dp,0,sizeof(dp)); 9 int a,b; 10 while(scanf("%d%d",&a,&b)!=EOF) 11 { 12 for(int i=15;i>=1;i--) 13 { 14 for(int j=15;j>=1;j--) 15 { 16 if(dp[i-1][j]) 17 dp[i][j]=max(dp[i][j],dp[i-1][j]+a); 18 if(dp[i][j-1]) 19 dp[i][j]=max(dp[i][j],dp[i][j-1]+b); 20 } 21 } 22 for(int i=15;i>=1;i--) 23 { 24 if(i==1||dp[i-1][0]) 25 { 26 dp[i][0]=max(dp[i][0],dp[i-1][0]+a); 27 } 28 if(i==1||dp[0][i-1]) 29 { 30 dp[0][i]=max(dp[0][i],dp[0][i-1]+b); 31 } 32 } 33 } 34 printf("%d\n",dp[15][15]); 35 return 0; 36 }