这题一开始用二维费用模板套上去,wa了,为什么呢?
我们想想,二维费用背包dp[v][m]状态设计的是体积不超过v以及重量不超过m的最大收益,看回这题,这题明确要求要从全班同学中选出一半,固定了数量,而不是不超过某个数,所以直接套背包模板不大行了。
那我们可以这么做,考虑dp[i][j][k]为前i个同学中用了j个同学,是否能到达k分,用可行性背包去做这题。
然后转移就可以啦。
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<sstream>
#include<queue>
#include<list>
#include<stack>
#include<bitset>
#include<cmath>
#include<map>
#define int long long
#define IO ios::sync_with_stdio(false)
using namespace std;
int dp[105][5005],v[10005],val[105],sum,n;
signed main()
{
IO;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>val[i];
sum+=val[i];
}
dp[0][0]=1;
for(int i=1;i<=n;i++)
{
for(int j=n/2;j>=1;j--)
{
for(int k=sum/2;k>=val[i];k--)
{
dp[j][k]=dp[j][k]|dp[j-1][k-val[i]];
}
}
}
for(int i=sum/2;i>=0;i--)
{
if(dp[n/2][i])
{
cout<<i;
break;
}
}
}