POJ-1276(多重背包)
2014-06-12 19:20
323 查看
典型多重背包,和经典问题的不同点在于:
经典问题基本上都是问最少用多少钞票(最多用多少钞票)可以兑换出来
本题问的是用这些钞票在不超过取款金额的条件下最多可以取出多少现金
用状态dp[i] = 1表示在当前条件下可以取出数量为i的现金,dp[i] = 0表示不能取出,dp过程中即可找到可取现金的最大值
经典问题基本上都是问最少用多少钞票(最多用多少钞票)可以兑换出来
本题问的是用这些钞票在不超过取款金额的条件下最多可以取出多少现金
用状态dp[i] = 1表示在当前条件下可以取出数量为i的现金,dp[i] = 0表示不能取出,dp过程中即可找到可取现金的最大值
#include <stdio.h> #include <string.h> #define max(a,b) ((a) > (b) ? (a) : (b)) int money, cash; int N, amount[10 + 1], value[10 + 1]; char dp[100000 + 1]; void zeroOnePack(int v) { int i = money; for(; i >= v; --i) if(dp[i] |= dp[i - v]) cash = max(cash, i); } void completePack(int v) { int i = v; for(; i <= money; ++i) if(dp[i] |= dp[i - v]) cash = max(cash, i); } void multiPack(int v, int c) { if(v * c >= money){ completePack(v); return; } int k = 1; for(; k < c; k <<= 1){ zeroOnePack(v * k); c -= k; } zeroOnePack(v * c); } int main() { int i, total; while(scanf("%d %d", &money, &N) == 2){ total = 0; /* input */ for(i = 0; i < N; ++i){ scanf("%d %d", &amount[i], &value[i]); total += amount[i] * value[i]; } /* judge */ if(money == 0 || N == 0) puts("0"); else if(total <= money) printf("%d\n", total); else{ /* initialize */ memset(dp, 0, money + 1); dp[0] = 1; cash = 0; /* multi-pack*/ for(i = 0; i < N; ++i){ if(amount[i]) multiPack(value[i], amount[i]); } /* print result */ printf("%d\n", cash); } } return 0; }
相关文章推荐
- 多重背包——POJ 1276
- poj 1276 多重背包模板
- POJ-1276-Cash Machine-多重背包
- POJ 1276 Cash Machine【多重背包DP】
- POJ - 1276 Cash Machine —— 多重背包 二进制优化
- poj 1276 Cash Machine(多重背包)
- poj1276(DP多重背包)
- POJ 1276 Time Machine【多重背包】
- POJ 1276 Cash Machine 多重背包
- poj 1276 Cash Machine (多重背包)
- POJ 1276 Cash Machine【多重背包】
- poj 1276 多重背包..
- POJ 1276 Cash Machine(多重背包问题)
- POJ1276 Cash Machine(多重背包问题)
- POJ1276 Cash Machine(多重背包)
- POJ 1276 Cash Machine 多重背包O(n*m)算法
- POJ 1276 Cash Machine 多重背包--二进制优化
- POJ 1276 Cash Machine(多重背包)
- poj1276(多重背包)
- 【DP|多重背包】POJ-1276 Cash Machine