【題解】洛谷P1064[NOIP2006]金明的預算方案 有依賴的揹包問題
阿新 • • 發佈:2018-12-14
我們把附件和它的主件歸到一組,其中主件為每組第一項編號為0。因為每組最多兩個附件,對於每一組,決策有以下五種(假定存在兩個附件): 1.不取這組 2.只取主件 3.取主件和附件1 4.取主件和附件2 5.取主件和附件1附件2 設 表示考慮到第 組容量為 時的最大價值 狀態轉移方程(假定存在兩個附件)
#include<cstdio> #include<vector> #include<algorithm> using namespace std; int n,m,v[61],p[61],w[61],tot,q[61],gro[61],f[32001]; vector<int>g[61]; int main() { //freopen("in.txt","r",stdin); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) scanf("%d%d%d",&v[i],&p[i],&q[i]),w[i]=v[i]*p[i]; for(int i=1;i<=m;i++) if(q[i]==0)g[++tot].push_back(i),gro[i]=tot; for(int i=1;i<=m;i++) if(q[i]>0)g[gro[q[i]]].push_back(i); for(int i=1;i<=tot;i++) for(int j=n;j>=0;j--) { if(j>=v[g[i][0]])f[j]=max(f[j],f[j-v[g[i][0]]]+w[g[i][0]]); if(g[i].size()>=2&&j>=v[g[i][0]]+v[g[i][1]])f[j]=max(f[j],f[j-v[g[i][0]]-v[g[i][1]]]+w[g[i][0]]+w[g[i][1]]); if(g[i].size()>=3) { if(j>=v[g[i][0]]+v[g[i][1]]+v[g[i][2]])f[j]=max(f[j],f[j-v[g[i][0]]-v[g[i][1]]-v[g[i][2]]]+w[g[i][0]]+w[g[i][1]]+w[g[i][2]]); if(j>=v[g[i][0]]+v[g[i][2]])f[j]=max(f[j],f[j-v[g[i][0]]-v[g[i][2]]]+w[g[i][0]]+w[g[i][2]]); } } printf("%d\n",f[n]); return 0; }
總結
一道典型的有依賴的揹包問題,要學會如何處理這類問題。