洛谷P2871与背包

背包用于寻找最优解,适用于在一堆数值中找寻符合题目要求条件的最优组合。

背包其实就是两个循环(蒟蒻的蒟蒻总结)

以P2871为例:在可装下的条件下找到最大价值组合。

起初想用(自认为是动归)(蒟蒻的思路):

倒着想:第五个有装下装不下两种情况:

1.装下:五个的价值和。

2装不下:判断“四个的最大价值和”与“三个的最大价值和”+“第五个的价值”哪个价值和更大?

   最大值即为所找的当今最大价值和。

但是这里有个疑似bug。就是可能“最大价值和的那三个”的重量加上第五个的重量可能还是超重。。。

尴尬。。。

蒟蒻不会修这段。(没本事使我警醒)于是去敲两个循环:也就是背包。

背包就是用数组来表示在某个重量下,通过循环找到最大价值和。

建立一个数组来存储最大价值和,下标表示重量,循环范围是从最大重量开始,到所循环的物品重量为止,依次相减。

所以第一个循环用来循环每件物品,内部的第二个循环用来输入、判断、存储该重量下的最大价值和。

判断的大致思路就是:

(例如现在循环到了重量为a[i],价值为b[i]的物品)用x[t]来表示重量为t时的存储价值。

比较x[t-a[i]]+b[i]与x[t]的价值哪个更大。表示就是:是占用a[i]的重量然后进入b[i]的价值所带来的价值和更多?还是原封不动更多?判断之后,赋值给x[t],表示的就是在符合重量的范围内的最大价值。

最后贴上代码警醒蒟蒻我:

#include<bits/stdc++.h>//万能头文件
using namespace std;
int c[23410],w[23410];
int main()
{
    int n,m,s=0,t=0,f[23410];
    ios_base::sync_with_stdio(0);//两行作用为加快cin效率
    cin.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>c[i]>>w[i];
    }
    for(int i=1;i<=n;i++)//背包的两个循环
    {
        for(int j=m;j>=c[i];j--)
        {
            f[j]=max(f[j],f[j-c[i]]+w[i]);
        }
    }
    cout<<f[m]<<endl;
    return 0;
}



阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页