背包问题的变化

输出方案

对于一个背包问题,我们已经求出了最优解.

现在要求你输出背包的选择方案.

(这个那么简单可以过了吧

分析

我们现在需要考虑的是如何记录这个状态.

很明显记录每个状态的最优值,是由状态转移方程的哪一项推出来的.

开数组\(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]\)的时候.

我们要选择后面这个方案.

猜你喜欢

转载自www.cnblogs.com/-guz/p/9641119.html