poj 1787 Charlie's Change(完全背包 或 多重背包 记录路径)
来源:互联网 发布:电子商务网络拓扑图 编辑:程序博客网 时间:2024/05/18 00:25
多重背包,但是可以用完全背包来做。
参考:http://www.cnblogs.com/kuangbin/archive/2012/09/20/2695803.html
#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int INF = 0x3f3f3f3f;const int MAXN = 10010;int dp[MAXN];int path[MAXN];int used[MAXN];int P;int v[4] = {1,5,10,25};int num[4];int res[100];void init(){ memset(res,0,sizeof(res)); memset(path,0,sizeof(path)); path[0] = -1; for(int i = 1; i <= P; ++i) dp[i] = -INF; dp[0] = 0;}void solve(){ for(int i = 0; i < 4; ++i) { memset(used,0,sizeof(used)); for(int j = v[i]; j <= P; ++j) { //dp[j-v[i]] >= 0如果不设这个条件。used会溢出 //而且dp[j-v[i]]<0的话,也没必要去更新,在这之前的状态组合不出来j-v[i] if(dp[j-v[i]]+1 > dp[j] && dp[j-v[i]] >= 0 && used[j-v[i]] < num[i]) { dp[j] = dp[j-v[i]]+1; used[j] = used[j-v[i]]+1; path[j] = j-v[i]; } } }}int main(){ while(scanf("%d",&P)) { scanf("%d %d %d %d",&num[0],&num[1],&num[2],&num[3]); if(P+num[0]+num[1]+num[2]+num[3] == 0) break; init(); solve(); if(dp[P] != -INF) { while(path[P] != -1) { res[P-path[P]]++; P = path[P]; } printf("Throw in %d cents, %d nickels, %d dimes, and %d quarters.\n",res[1],res[5],res[10],res[25]); } else printf("Charlie cannot buy coffee.\n"); } return 0;}
多重背包:
参考:http://blog.csdn.net/libin56842/article/details/9470687
学到了记录一种多重背包记录路径的方法。
#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int N = 10010;int dp[N*10];int path[N];int cent[4] = {1,5,10,25};int num[4];int res[30];int P;void CompletePack(int pos){ for(int j = cent[pos]; j <= P; ++j) { if(dp[j-cent[pos]]+1 > dp[j]) { dp[j] = dp[j-cent[pos]]+1; path[j] = pos*N+j-cent[pos]; } }}void ZeroOnePack(int pos, int k){ for(int j = P; j >= cent[pos]*k; --j) { if(dp[j-k*cent[pos]]+k > dp[j]) { dp[j] = dp[j-k*cent[pos]]+k; path[j] = pos*N+j-k*cent[pos]; } }}void MultiplePack(){ for(int i = 0; i < 4; ++i) { if(num[i]*cent[i] >= P) CompletePack(i); else { int temp = num[i]; for(int k = 1; k <= temp; k *= 2) { ZeroOnePack(i,k); temp -= k; } if(temp) ZeroOnePack(i,temp); } }}int main(){ int t; while(scanf("%d",&P)) { t = P; for(int i = 0; i < 4; ++i) { scanf("%d",&num[i]); t += num[i]; } if(!t) break; memset(path,0,sizeof(path)); memset(res,0,sizeof(res)); for(int i = 1; i <= P; ++i) dp[i] = -N; dp[0] = 0; MultiplePack(); if(dp[P] < 0) { printf("Charlie cannot buy coffee.\n"); continue; } while(P) { int s1 = path[P]/N;//s1表示货币的种类 int s2 = path[P]%N;//(P-s2)表示这种货币一共多少金额 res[cent[s1]] += (P-s2)/cent[s1]; P = s2; } printf("Throw in %d cents, %d nickels, %d dimes, and %d quarters.\n",res[1],res[5],res[10],res[25]); }}
阅读全文
0 0
- poj 1787 Charlie's Change(完全背包 或 多重背包 记录路径)
- POJ 1787 Charlie's Change(多重背包+记录路径)
- POJ 1787 Charlie's Change 记录路径的多重背包
- poj 1787 Charlie's Change【多重背包可行性+记录路径】
- POJ 1787 - Charlie's Change(完全背包+路径记录)
- Poj 1787 Charlie's Change(多重背包 或者 记录的完全背包)
- POJ-1787 Charlie's Change( 多重背包记录方案)
- POJ - 1787 Charlie's Change(完全背包和路径纪录)
- POJ 1787 Charlie's Change / 完全背包
- 动态规划,多重背包,保存路径,用完全背包的方法做多重背包(Charlie's Change,poj 1787)
- POJ1787:Charlie's Change(记录路径的多重背包)
- poj1787 Charlie's Change (多重背包+记录路径)
- poj 1787 Charlie's Change(打印路径的多重背包 ->交易数量最大化)
- 【POJ】1787 Charlie's Change(完全背包)
- POJ 题目1787 Charlie's Change(完全背包)
- poj 1787 Charlie's Change(背包问题输出路径)
- zoj2156 Charlie's Change 完全背包+路径记录
- poj1787 Charlie's Change(多重背包+路径)
- 练习 2017-08-14 字符流读取/写出/拷贝
- 哈希---邻接表(简单实现)
- HTTP常见状态码 200 301 302 404 500
- Error:CreateProcess error=216, 该版本的 %1 与您运行的 Windows 版本不兼容。请查看计算机的系统信息,了解是否需要 x86 (32 位)或 x64 (64 位)
- SSS1629,SSS1629一级代理,USB游戏耳机方案,USB麦克风方案,台湾鑫创一级代理商
- poj 1787 Charlie's Change(完全背包 或 多重背包 记录路径)
- 费用流模板 hdu1533
- 关于WebRTC初接触2
- 用知识来计算出你表白成功的概率多大
- vs2015下的c#项目的exe发布
- Python3之继承,归一化设计
- JSP九大内置对象
- Spring MVC 教程,快速入门,深入分析
- android 打开高德地图并 指定起始与结束位置 接口