非常板子的DP背包问题,不过板子也有板子的好处,可以让修补骑士快速上手熟悉某个知识点的写法
在这里就说两个我犯的错吧
1:我们都知道,对于每一个元素选或者不选,我们是从后向前的(防止多选),但是我们写循环要写成for(int y = allwei/2;y >= weight[r];y--)而不是>=0,原因是因为我们使用了max来记录最大值,对于装不下的理所应当为0,但是可能就变成了dp[y - weight[r]] + weight[r]),这里dp是0,但是weight不是,会造成错误的结果。所以说对于根本装不下的r,我们是需要显示说明的
(如果剩余空间根本装不下,那当然是保持不变了,刚好还契合了一维容器的特性)
2:修补骑士一开始以为单位价值为1,结果发现还不如原汤化原食,价值也变为weight,到时候直接一并输出了
AC代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n;
cin>>n;
vector<int> weight(n,0);
for(int r = 0;r < n;r++)
{
cin>>weight[r];
}
int allwei = accumulate(weight.begin(),weight.end(),0);
//哇,又有没用的新关键词
vector<int> dp((allwei/2) + 1,0);
for(int r = 0;r < n;r++)
{
for(int y = allwei/2;y >= weight[r];y--)
{
dp[y] = max(dp[y],dp[y - weight[r]] + weight[r]);
}
}
cout<<dp[allwei/2]<<" "<<allwei - dp[allwei/2]<<endl;
return 0;
}