ZOJ1366 POJ1276 Cash Machine 经典多重背包问题
来源:互联网 发布:公司域名邮箱收费标准 编辑:程序博客网 时间:2024/06/09 21:55
这是一条非常经典的题,是0/1背包问题的变种,详细可以看看《背包9讲-多重背包问题》。简单说一下,对于n1 D1 n2 D2 ... nN DN,n为D的数量,则可以把n分解为k1=1,k2=2,k3=4,k4=8...km,且k1+k2+...km=n,其中k1,k2...km-1为2的幂,km不一定是2的幂。这个要表达清楚是很困难的,你们可以看一下《背包9讲》。同时背包问题有两种不同的问法,即恰好装满背包和不要求装满背包,大家可以看一下以下这段解释。
以下摘自《背包9讲》
我们看到的求最优解的背包问题题目中,事实上有两种不太相同的问法。有的题目要求“恰好装满背包”时的最优解,有的题目则并没有要求必须把背包装满。一种区别这两种问法的实现方法是在初始化的时候有所不同。如果是第一种问法,要求恰好装满背包,那么在初始化时除了f[0]为0其它f[1..V]均设为-∞,这样就可以保证最终得到的f[N]是一种恰好装满背包的最优解。如果并没有要求必须把背包装满,而是只希望价格尽量大,初始化时应该将f[0..V]全部设为0。为什么呢?可以这样理解:初始化的f数组事实上就是在没有任何物品可以放入背包时的合法状态。如果要求背包恰好装满,那么此时只有容量为0的背包可能被价值为0的nothing“恰好装满”,其它容量的背包均没有合法的解,属于未定义的状态,它们的值就都应该是-∞了。如果背包并非必须被装满,那么任何容量的背包都有一个合法解“什么都不装”,这个解的价值为0,所以初始时状态的值也就全部为0了。这个小技巧完全可以推广到其它类型的背包问题,后面也就不再对进行状态转移之前的初始化进行讲解。
代码如下
/******************************************************************************* * Author : Neo Fung * Email : neosfung@gmail.com * Last modified : 2011-07-18 17:41 * Filename : ZOJ1366 POJ1276 Cash Machine.cpp * Description :http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1366http://poj.org/problem?id=1276 * *****************************************************************************/// ZOJ1366 POJ1276 Cash Machine.cpp : Defines the entry point for the console application.//// #include "stdafx.h"#include <fstream>#include <stdio.h>#include <iostream>#include <string.h>#include <string>#include <vector>#include <stack>#include <deque>#include <map>#include <math.h>#include <algorithm>#include <numeric>#include <functional>#include <memory.h>using namespace std;int main(void){// ifstream cin("data.txt");int cash,N;int n,D;int temp;vector<int> cashVec;int *DP=new int[100001];int power[]={1,2,4,8,16,32,64,128,256,512};while(cin>>cash>>N){for (int i=0;i<=cash;++i){DP[i]=0;}DP[0]=0;cashVec.clear();cashVec.push_back(0);for(int i=1;i<=N;++i){cin>>n>>D;if(!n) temp=0;elsetemp = log((n+1)*1.0) / log(2.0) + 0.99999999;for(int j=0;j<temp;++j){if(n>power[j]){cashVec.push_back(D*power[j]);n -=power[j];}else{cashVec.push_back(n*D);}}}if(cash == 0 || N==0){cout<<0<<endl;continue;}for(int i=1;i<cashVec.size();++i)if (cash < cashVec.at(i)){continue;}else{for(int j=cash;j>= cashVec.at(i);--j){// if(j<=cashVec.at(i))DP[j] = max(DP[j],DP[j-cashVec.at(i)]+cashVec.at(i));}}cout<<DP[cash]<<endl;}cashVec.clear();delete []DP;return 0;}
- ZOJ1366 POJ1276 Cash Machine 经典多重背包问题
- POJ1276 Cash Machine(多重背包问题)
- poj1276(Cash Machine + 多重背包)
- POJ1276:Cash Machine(多重背包)
- POJ1276:Cash Machine(多重背包)
- poj1276 Cash Machine-多重背包
- POJ1276:Cash Machine(多重背包)
- POJ1276-Cash Machine(多重背包)
- zoj1366 Cash Machine (多重背包基础)
- poj1276--Cash Machine(多重背包判可达)
- POJ1276 Cash Machine(多重背包~~)
- poj1276 Cash Machine(多重背包)
- POJ1276 Cash Machine(多重背包)
- poj1276 Cash Machine(多重背包)
- [背包]poj1276 Cash Machine
- 背包(2)poj1276 Cash Machine(多重背包)
- poj1276——Cash Machine(多重背包)
- pOJ1276 Cash Machine(背包)
- PHP字符串截断(中英文)
- 二叉树的链表存储
- directshow 抓取视频帧
- 交换机VLAN及中继配置
- 如何用C语言开发DSP嵌入式系统
- ZOJ1366 POJ1276 Cash Machine 经典多重背包问题
- VC INI文件的读写
- java字符编码原理解析
- MySql的一条语句Insert插入多行的写法和MySql在插入时间字段语句的写法
- poj 1936 我的ACM之旅开始了~~~吼吼
- sql server
- MFC RTTI 仿真
- 关于JSP页面中的pageEncoding和contentType两种属性的区别
- SqlServer分布式查询