您的位置:首页 > 其它

背包问题(01)

2018-02-01 14:34 302 查看

一,01背包

题目概述:why(魏泓宇)用你们的程序知道了在他在旅行时能拿的最大价值(完全背包),但他又发现了一个和严重的问题,那就是物品数不够了,每种只剩下一个了,所以他又来找你帮忙。(有N件物品和一个容量为V的背包。第i件物品的体积是a[i][0],价值是a[i][1]。求解将哪些物品装入背包可使价值总和最大)
输入:N   V

a[1][0]    a[1][1]   //1号物品的体积和价值

a[2][0]   a[2][1]    //2号物品的体积和价值

.......

a
[0]   a
[1]    //N号物品的体积和价值

输出:why最多能带上的价值

解析:这道题我们要倒的推上去,想要算出f[i][v](i为第i件物品,v为体积为v时,f[i][v]代表着当有前i件物品最大体积为v时的最大价值),我们就要知道f[i-1][v]和f[i-1][v-a[i][0]],我们可以要第i件物品,那么f[i][v]=f[i-1][v-a[i][0]]+a[i][1],如果不要它,那么f[i][v]=f[i-1][v]。我们只需要比较一下他们的大小,然后选大的即可:f[i][v]=max(f[i-1][v],f[i-1][v-a[i][0]]+a[i][1]);注明:“max”是事先定义好的函数。

这样我们只需枚举i,再枚举v就行了,再进行比较就可以了。

但你仔细观察既可以发现,其实它的空间是可以优化的,因为我们如果把v从大到小枚举就只需要一维了,我们需要的答案只是最后一行的最后一个数,上面的并不需要,而且如果把v倒地枚举,f[i][v]所需要的数都是那时还没有被跟新的,可以直接使用,所以我们的程序可以转成更加简单一些。

主要代码:

for(int i=1;i<=m;i++)
{
for(int v=n;v>=0;v--)
{
if(v>=a[i][0])
f[v]=max(f[v],f[v-a[i][0]]+a[i][1]);
}
}


很简短,是吧
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: