您的位置:首页 > 其它

背包问题(完全)

2018-02-01 13:30 204 查看

一,完全背包

题目概述:why(魏泓宇)在寒假里要去旅行了,他要带上一些东西,有N种,要放进一个容量为V的背包,每种物品都有无数种。第i种物品的体积是a[i][0],价值是a[i][1]。why想要尽可能的带上价值最大的东西,但他懒得很,所以他想要你来帮他编一个程序,告诉他最多可以带上多大的价值。(真实题目:采药)

输入:N   V

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

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

.......

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

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

解析:这是一道很很很经典的DP,它的主要程序就是循环加判断加状态转移方程。

我们要用DP的思想来想 ,DP的思想就是用已知的量通过状态转移方程来进行计算未知的量,也就是从一个阶段到后一个阶段。现在我们来想这道题的阶段是什么。他要求的是V体积时的最大价值,其实是可以通过前面较小的体积的最大价值得出的,这样一来就可以得出我们的阶段就是体积了,因为每一体积的最大价值都是可以通过前面所有的体积的最大值得出的。

然后我们就可以确定第一重的循环,就是从小到大枚举背包体积,求价值最大值,在里面进行状态转移。

接下来,我们来想如何进行状态转移:想一想,就能想明白其实当前价值最大值,是前面的最大值再放入物品得到的,再找出其中最大的,纪即为当前最大值。

那么,我们就可以再通过两重循环来分别枚举前面的价值最大值和物品,如果这俩者的体积之和并不超过本次循环的体积,而且价值大于之前的价值,就像这样”打擂台“,直到找到最大值。

好了,写的这么麻烦,其实代码很简短: for(int i=1;i<=n;i++)//枚举最小体积
{
for(int j=0;j<i;j++)//枚举之前的最小体积的最大价值
{
for(int k=1;k<=m;k++)//枚举所有的物品
{
if(a[k][0]+f[j][0]<=i)//比较体积是否在当前体积范围内
{
if(a[k][1]+f[j][1]>f[i][1])//比较价值是否比之前的价值大
{
f[i][0]=a[k][0]+f[j][0];
f[i][1]=a[k][1]+f[j][1];//将新的数据放入
}
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: