//揹包問題總結(根據揹包九講) 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 的物品,
//當正序時
物品在容量足夠的狀況下能夠一直取ios
但逆序時spa
就沒法重複選擇了code
#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; } }