POJ-1276 多重背包问题
来源:互联网 发布:imovie的windows版 编辑:程序博客网 时间:2024/06/05 13:35
Cash Machine
题意:输入第一行cash N n1 D1 n2 D2 ... nN DN ,D1表示一种面值的零钱,n1表示D1可以使用的数量。一共有N种零钱。需要找出用这些零钱可以组成的不超过cash的最大数额。
这是一道多重背包的问题,和poj-1014 多重背包问题类似,需要先转化成01背包,再用01背包问题的方法求解。转换的代码如下,a[i]是转换前第i个零钱的数量,b[i]是转换前第i个零钱的面值,w[count]是转换后的第count个零钱的面值,转换后每种零钱只有一个,但是可以组合成转换前的各种组合。
int count = 1;for(int i=1;i<=n;i++){int c=1;while(a[i]-c>0){w[count++] = c*b[i];a[i] -= c;c = c << 1;}w[count++] = a[i]*b[i];}
之后用01背包的方法计算,因为没有背包问题中体积这一参数,可以将体积设置为与价格一致。状态转移方程为dp[j] = max(dp[j],dp[j-w[i]]+w[i]),用一维数组来表示需要从后往前变化,每一行已经扫描到的部分属于第i行,未扫描到的部分属于第i-1行,j表示第j列。代码如下:
for( i=1;i<count;i++){for(int j=all;j>=w[i];j--){dp[j] = max(dp[j],dp[j-w[i]]+w[i]);}}
完整的AC代码如下:
#include<iostream>#include<cstring>#include<math.h>using namespace std;int all,n;int a[210],b[210],w[210],dp[110000];void dp_fun(){//多重变换为01背包 memset(dp,0,sizeof(dp));int count = 1;for(int i=1;i<=n;i++){int c=1;while(a[i]-c>0){w[count++] = c*b[i];a[i] -= c;c = c << 1;}w[count++] = a[i]*b[i];}int i;for( i=1;i<count;i++){for(int j=all;j>=w[i];j--){dp[j] = max(dp[j],dp[j-w[i]]+w[i]);}}cout << dp[all]<<endl;} int main(){while(cin >> all){cin >> n;for(int i=1;i<=n;i++){cin >> a[i] >> b[i];}dp_fun();}return 0;}
阅读全文
0 0
- POJ 1276 多重背包问题
- poj 1276 多重背包问题
- poj 1276 多重背包问题
- POJ-1276 多重背包问题
- POJ 1276 Cash Machine 多重背包问题
- poj 1276 多重背包..
- POJ--1276:多重背包
- POJ 1276 多重背包
- POJ 1276 多重背包
- poj 1276 多重背包
- poj 1276 多重背包
- poj 1276 多重背包
- POJ 1276 多重背包
- POJ 1276 多重背包
- POJ 1276(多重背包)
- poj 1276 多重背包
- poj 1276 多重背包
- POJ 1742 多重背包问题
- SpringMVC在Controller层中注入request的坑
- Codeforces Gym 101164 G. Pokemons
- .NET体系
- jqgrid--rownumbers添加标题头
- 观察者模式
- POJ-1276 多重背包问题
- Android引导页消失进入软件
- Codeforces Gym 101164 H. Pub crawl (凸包)
- 【剑指offer】题45:圆圈中最后剩下的数字
- java.util.HashMap
- 归并排序
- Codeforces Gym 101164 K. Cutting (字符串 HASH)
- V4L2常用命令详解
- Nginx--反向代理、负载均衡、缓存、fpm