#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;
#define CLR(c,v) (memset(c,v,sizeof(c)))
const int INF = 1<<30;
const int inf = -(1<<30);
const int M = 1e5 + 10;
int dp[M];
int v[M];
int n_bag , max_value;
#define max_cost max_value
void CompletePack(int cost, int value){
for (int i = cost ; i <= max_cost ; i++){
if (dp[i] < dp[i-cost] + value)
dp[i] = dp[i-cost] + value;
}
}
void ZeroOnePack(int cost,int value){
for (int i = max_cost ; i >= cost ; i--){
if (dp[i] < dp[i-cost] + value){
dp[i] = dp[i-cost] + value;
}
}
}
void MultiplePack(int cost , int value ,int amount){
if (max_cost < cost * amount){ // 全部数量的物品 放不下,视为数量过多,完全背包
CompletePack(cost , value);
}else{
for (int k = 1 ; k <= amount ; k <<= 1){ // 二进制优化
if (max_cost >= cost*k){
ZeroOnePack(cost*k , value*k);
amount -= k;
}
}
ZeroOnePack(cost*amount , value*amount); // 剩余物品
}
}
int main(){
//freopen("in.txt","r",stdin);
while(cin >> n_bag >> max_value && n_bag && max_value){
CLR(dp,0);
for (int i = 1 ; i <= n_bag ; i++){
cin >> v[i];
}
for (int i = 1 ; i <= n_bag ; i++){
int n; // 当前物品的个数
cin >> n;
MultiplePack(v[i] , v[i] , n);
}
int ans = 0;
for (int i = 1 ; i <= max_value ; i++){
if (dp[i] == i)
ans++;
}
cout << ans << endl;
}
return 0;
}
HDU 2844 Coins -- 多重背包
最新推荐文章于 2018-11-10 17:03:50 发布