zoukankan      html  css  js  c++  java
  • 背包问题总结

    //背包问题总结(根据背包九讲) 2019 9/26 会更新完
    //0 - 1背包变种问题 (HDU3466)
    //唔,0 1背包太简单了,主要是排序
    //因为DP v 是从 m 到 w[i]的,但是现在增加了一个限定值,如果限定值小于等于w[i]的话,无影响,但是如果大于w[i]的话,就会存在一个q - p的差的范围是0
    //所以应该将 差值范围小的尽可能排放在前面 so 根据 q - p差值范围排序
    //或者假设 物品 A PA,QA
    //     物品 B PB,QB
    //  先放物品A v = PA + QB, 先放物品B v = PB + QA
    //因此如果得先放A物品 则 PA + QB < PB + QA
    //QA - PA > QB - PB
    //因为DP是逆序的嘛,反一下就好了,画个图想想
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    using namespace std;
    const int maxn = 5e3 + 15;
    int f[maxn];
    int n,m;//n件物品
    typedef struct
    {
        int w,limit,v;
    }article;
    vector<article> vr;
    bool cmp(const article& a1,const article& a2)
    {
        return a1.w + a2.limit > a2.w + a1.limit;
    }
    int main()
    {
        while(cin>>n>>m)
        {
            vr.clear();
            memset(f,0,sizeof(f));//背包
            article tmp;
            for(int i=0;i!=n;++i)
            {
                cin>>tmp.w>>tmp.limit>>tmp.v;
                vr.push_back(tmp);
            }//放入物品
            sort(vr.begin(),vr.end(),cmp);
            for(int i=0;i!=n;++i)
            {
                int maxValue = max(vr[i].limit,vr[i].w);
                for(int v=m;v>=maxValue;--v)
                {
                    f[v] = max(f[v],f[v-vr[i].w]+vr[i].v);
                }
            }
            cout<<f[m]<<endl;
        }
    }
    

      

    //完全背包问题(物品的个数无限)
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    //完全背包问题无非是把顺序相反一下,因为如果逆序,eg 有 容量为 v 的背包 ,有一个 v 为3 ,w 为4 的物品,
    //当正序时

     

     物品在容量足够的情况下可以一直取

     但逆序时

     

     就无法重复选择了

    #define inf (0x3f3f3f3f)
    using namespace std;
    const int maxn = 1e4 + 15;
    int coinw[512];
    int coinv[512];
    int arr[maxn];
    int main()
    {
        int T,e,f,n;  cin>>T;
        while(T--)
        {
            cin>>e>>f>>n;
            int value = f - e;//(limit)
            for(int i=1;i<=n;++i)
                cin>>coinv[i]>>coinw[i];//value和weight
            memset(arr,inf,sizeof(arr));
            arr[0] = 0;
            for(int i=1;i<=n;++i)
            {
                for(int j=coinw[i];j<=value;++j)
                    arr[j] = min(arr[j],arr[j-coinw[i]]+coinv[i]);
            }
            if(arr[value]!=inf)
                cout<<"The minimum amount of money in the piggy-bank is "<<arr[value]<<"."<<endl;
            else
                cout<<"This is impossible."<<endl;
        }
    }
    不怕万人阻挡,只怕自己投降。
  • 相关阅读:
    POJ 2342 Anniversary party
    hdu 4339 Query
    Strlcpy和strlcat——一致的、安全的字符串拷贝和串接函数
    C语言直方图 && EOF释疑
    Pig 安装和使用
    时钟、背景音乐、背景图片
    字符串拷贝函数memcpy()、strncpy()和snprintf()性能之比较
    内核编译时提示错误error: sys/types.h: No such file or directory
    ubuntu中liveCD、desktop与alternate版本的区别
    恰恰是实现梦想的可能性,才使生活变得有趣
  • 原文地址:https://www.cnblogs.com/newstartCY/p/11596070.html
Copyright © 2011-2022 走看看