【HNOI 2007】夢幻島寶珠
阿新 • • 發佈:2018-12-16
題目描述
給你 顆寶石,每顆寶石都有重量和價值。要你從這些寶石中選取一些寶石,保證總重量不超過 ,輸出最大的總價值。保證每顆寶石的重量符合 。
演算法分析
設 表示揹包容量為 時的最大總價值, 相同時的轉移等同 0/1 揹包, 不同時有 。 我好菜啊
程式碼實現
#include <cstdio>
#include <cstring>
#include <algorithm>
#define UPD(x,y) x=std::max(x,y)
#define Min(x,y) std::min(x,y)
int n,w,f[35][1005];
int main() {
while(scanf("%d%d",&n,&w)==2&&((~n)||(~n))) {
memset(f,0,sizeof(f));
for(int i=0;i<n;++i) {
int a,b=0,v;
scanf ("%d%d",&a,&v);
while(!(a&1)) {++b;a>>=1;}
for(int j=1000;j>=a;--j) UPD(f[b][j],f[b][j-a]+v);
}
int top=-1;for(int i=w;i;i>>=1) ++top;
for(int i=1;i<=top;++i) {
for(int j=1000;j>=0;--j) for(int k=0;k<=j;++k)
UPD(f[i][j],f[i][j-k]+f[i-1][Min(1000,(k<<1)|(w>>(i-1)&1))]);
}
printf("%d\n",f[top][1]);
}
return 0;
}