背包问题总结

//背包问题总结(根据背包九讲) 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
#include
#include
#include
#include
using namespace std;
const int maxn = 5e3 + 15;
int f[maxn];
int n,m;//n件物品
typedef struct
{
    int w,limit,v;
}article;
vector
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<

  

//完全背包问题(物品的个数无限)
#include
#include
#include
#include
//完全背包问题无非是把顺序相反一下,因为如果逆序,eg 有 容量为 v 的背包 ,有一个 v 为3 ,w 为4 的物品,
//当正序时
背包问题总结_第1张图片

 

 背包问题总结_第2张图片

 

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

 但逆序时

背包问题总结_第3张图片

 

 背包问题总结_第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 "<"."<<endl;
        else
            cout<<"This is impossible."<<endl;
    }
}

 

你可能感兴趣的:(背包问题总结)