HDUOJ 2844 Coins

来源:互联网 发布:美工全职 编辑:程序博客网 时间:2024/06/11 10:27
#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 1000000007using 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;}

原创粉丝点击