#ifdef _DEBUG
#pragma warning(disable : 4996)
#endif
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
#include <sstream>
#include <utility>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <cctype>
#define CLEAR(a, b) memset(a, b, sizeof(a))
#define CLOSE() ios::sync_with_stdio(false)
#define IN() freopen("in.txt", "r", stdin)
#define OUT() freopen("out.txt", "w", stdout)
#define PF(a) printf("%d\n", a)
#define SF(a) scanf("%d", &a)
#define SFF(a, b) scanf("%d%d", &a, &b)
#define SFFF(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define FOR(i, a, b) for(int i = a; i < b; ++i)
#define LL long long
#define maxn 100005
#define maxm 105
#define MOD 1000000007
#define INF 1000000007
using namespace std;
//-------------------------CHC------------------------------//
//HDUOJ 2844 Coins
//再次看见多重背包,第一次做时采用了拆分为01背包和完全背包的方法,复杂度为m*sigma(c[i]),显然超时。
//改用二进制拆分法
int dp[maxn];
int v[maxm], c[maxm];
int n, m;
void ZeroOnePack(int w, int v) {
for (int i = m; i >= w; --i)
dp[i] = max(dp[i], dp[i - w] + v);
}
void CompletePack(int w, int v) {
FOR(i, w, m + 1)
dp[i] = max(dp[i], dp[i - w] + v);
}
void MultPack(int w, int v, int c) {
if (c*v >= m) {
CompletePack(w, v);
return;
}
int k = 1;
while (k <= c) {
ZeroOnePack(k*w, k*v);
c = c - k;
k <<= 1;
}
ZeroOnePack(c*w, c*v);
}
int main() {
while (SFF(n, m)) {
if (n == 0 && m == 0) break;
CLEAR(dp, 0);
dp[0] = 0;
FOR(i, 0, n) SF(v[i]);
FOR(i, 0, n) SF(c[i]);
FOR(i, 0, n)
MultPack(v[i], v[i], c[i]);
int ans = 0;
//定义状态为w是v的最大值
FOR(i, 1, m + 1) {
//printf("dp = %d\n", dp[i]);
if (dp[i] == i) ans++;
}
PF(ans);
}
return 0;
}
HDUOJ 2844 Coins
最新推荐文章于 2019-03-22 08:29:34 发布