原题链接 https://www.luogu.org/problem/P2663
很容易看出来是个背包问题嘛:
体积是总分的一半,求最高分,每个同学选或不选,是个 01背包问题。
自信地交上去之后发现只有 90pts ,为什么呢?
是不是忘了个条件啊喂,人家还要选 n/2 个人呐!
多一个条件就加一个维度。——zhx
有了第二个限制:重量是 n/2 ,这样就从一个 01背包问题转化成了二维背包问题,我们只需在 for 循环中多枚举一层 1~n/2 问题就搞定了。
上AC代码:
#include<iostream> #include<cstdio> using namespace std; int read() {char ch=getchar();int a=0,x=1;while(ch<'0'||ch>'9'){if(ch=='-') x=-x;ch=getchar();}while(ch>='0'&&ch<='9'){a=(a<<1)+(a<<3)+(ch-'0');ch=getchar();}return a*x; } long long n,sum; long long test[1001]; long long f[101][10001]; //f[i][j]:选了i个人总分不超过j的最大分数 int main() {n=read();for(int i=1;i<=n;i++){test[i]=read(); //每个人的分数 sum+=test[i]; //总分 }for(int k=1;k<=n;k++) //枚举每个人 {for(int i=n/2;i>=1;i--) //限制人数的这个条件(重量) {for(int j=sum;j>=test[k];j--) //限制分数的这个条件(体积) {f[i][j]=max(f[i][j],f[i-1][j-test[k]]+test[k]); //选或不选取max }}}printf("%lld",f[n/2][sum/2]);return 0; }