P2663 越越的组队
原题链接 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; }