输出方案
对于一个背包问题,我们已经求出了最优解.
现在要求你输出背包的选择方案.
(这个那么简单可以过了吧
分析
我们现在需要考虑的是如何记录这个状态.
很明显记录每个状态的最优值,是由状态转移方程的哪一项推出来的.
开数组\(g[i][v]\)记录状态\(f[i][v]\)是由状态转移方程哪一项推出.
//以01背包一维写法为例.
code
for(int i=1;i<=n;i++)
{
for(int j=V;j>=c[i];j--)
{
if(f[j]<f[j-c[i]]+w[i])
{
f[j]=f[j-c[i]]+w[i];
g[i][j]=true;///选第i件物品
}
else vis[i][j]=false;///不选第i件物品
}
}
输出
code
扫描二维码关注公众号,回复:
3167992 查看本文章
int T=V;
for(int i=n;i>=1;i--)
{
if(g[i][T])
{
printf("used %d",i);
T-=c[i];//减去物品i的体积.
}
}
//不保证代码正确qwq
再放一下状态转移方程.
\(f[i][v]=max(f[i-1][v],f[i-1][v-c[i]]+w[i]\)
\(f[j]=max(f[j],f[j-c[i]+w[i])\)
二维状态可以省去g数组,只需要判断\(f[i][v]\)是等于\(f[i-1][v]\)还是等于\(f[i-1][v-c[i]]+w[i]\)就能输出方案.
一维状态好像不能,我不会啊qwq
输出字典序较小的最优方案
感觉sort一下就可以吧
根据原文叙述来看,是将物品逆序排列一下.
与上面输出方案的解法相同.
唯一需要判断的是:
当\(f[i][v]==f[i-1][v]\) 并且\(f[i][v]==f[i-1][v-c[i]]+w[i]\)的时候.
我们要选择后面这个方案.