题目链接:点击打开链接
题目大意:略。
解题思路:三维数组:dp[i][j][k] + 01背包;注意对每个坐标(互相独立)进行 01背包。
AC 代码
#include<bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof a); using namespace std; typedef long long ll; // 01背包 - 三维数组,前面两个相当于二维数组的[i],最后一个相当于二维数组的[j] int dp[310][310][310]; int main() { int m,n,x; while(~scanf("%d%d",&m,&n)) { mem(dp,0); int rs=0; for(int i=1;i<=n;i++) for(int j=1;j<=i;j++) { scanf("%d",&x); // for(int k=x;k<=m;k++) // 也可以AC // { // dp[i][j][k]=max(max(dp[i-1][j-1][k],dp[i-1][j][k]),max(dp[i-1][j][k-x]+x,dp[i-1][j-1][k-x]+x)); // } for(int k=0;k<=m;k++) // 对每个坐标进行 01背包 { if(k>=x) dp[i][j][k]=max(max(dp[i-1][j-1][k],dp[i-1][j][k]),max(dp[i-1][j][k-x]+x,dp[i-1][j-1][k-x]+x)); else dp[i][j][k]=max(dp[i-1][j-1][k],dp[i-1][j][k]); } rs=max(rs,dp[i][j][m]); // 因为会集中在每个坐标(01背包)的末尾,所以对末尾取max即可 } printf("%d\n",rs); // dp[n][n][m] 这种是错误的思路,因为这只是代表最后一次的01背包的max,而每次坐标撸第三个for_k的时候,它们每个坐标之间都是互相独立的 } return 0; }