http://acm.hdu.edu.cn/showproblem.php?pid=2844
二进制优化的多重背包模板题
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 110;
struct coin{
int value,num;
}node[N];
int n,v,dp[N*1000];
void onezeropack(int cost){
for(int i=v; i>=cost; i--)
dp[i] = max(dp[i], dp[i-cost]+cost);
}
void completepack(int cost){
for(int i=cost; i<=v; i++)
dp[i] = max(dp[i], dp[i-cost]+cost);
}
void multiplepack(int cost, int n){///二进制优化
if(cost * n >= v){
completepack(cost);
return;
}
int k = 1;
while(k < n){
onezeropack(cost * k);
n -= k;
k <<= 1;
}
onezeropack(n * cost);
}
int main(){
// freopen("in.txt", "r", stdin);
while(scanf("%d%d",&n,&v) == 2){
if(!n && !v) break;
for(int i=1; i<=n; i++)
scanf("%d",&node[i].value);
for(int i=1; i<=n; i++)
scanf("%d",&node[i].num);
memset(dp, 0, sizeof(dp));
for(int i=1; i<=n; i++)
multiplepack(node[i].value, node[i].num);
int ans = 0;
for(int i=1; i<=v; i++)
if(dp[i] == i) ans++;
printf("%d\n",ans);
}
return 0;
}