L3-001. 凑零钱 - 【01背包 + 记录路径 + 裸裸裸题】
2017-10-06 20:30
330 查看
L3-001. 凑零钱
时间限制200 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越
韩梅梅喜欢满宇宙到处逛街。现在她逛到了一家火星店里,发现这家店有个特别的规矩:你可以用任何星球的硬币付钱,但是绝不找零,当然也不能欠债。韩梅梅手边有104枚来自各个星球的硬币,需要请你帮她盘算一下,是否可能精确凑出要付的款额。
输入格式:
输入第一行给出两个正整数:N(<=104)是硬币的总个数,M(<=102)是韩梅梅要付的款额。第二行给出N枚硬币的正整数面值。数字间以空格分隔。输出格式:
在一行中输出硬币的面值 V1 <= V2 <= … <= Vk,满足条件 V1 + V2 + … + Vk = M。数字间以1个空格分隔,行首尾不得有多余空格。若解不唯一,则输出最小序列。若无解,则输出“No Solution”。注:我们说序列{A[1], A[2], …}比{B[1], B[2], …}“小”,是指存在 k >= 1 使得 A[i]=B[i] 对所有 i < k 成立,并且 A[k] < B[k]。
输入样例1:
8 95 9 8 7 2 3 4 1
输出样例1:
1 3 5输入样例2:
4 87 2 4 3
输出样例2:
No Solution题意:给你n和m,表示有n种硬币,总价为m元,然后给你n个数,表示有n个单位货币,问你能不能由这n个货币其中的一些恰好组成m元,如果可以的话,从小到大输出;
分析: 乍一看可以dfs,但是看了时限,……… 还是老老实实背包吧,直接一个01背包记录路径即可,就是中间加个排序,因为要求是要从小到大来输出, 这里呢简单解释下 pre[j]=j−v[i],仔细看下就能发现存的恰好是dp数组里的坐标, 就和单链表里的next数组类似,ans数组呢是为了输出时使用的,仔细体会体会。
参考代码
#include<bits/stdc++.h> using namespace std; const int N = 1e5 + 10; int pre ,dp ,v ,ans ; void p(int x){ if(pre[x] == 0){ cout<<ans[x];return; } p(pre[x]); cout<<' '<<ans[x]; } int main(){ ios_base::sync_with_stdio(0); int n,m;cin>>n>>m; for(int i = 0;i < n;i++)cin>>v[i]; for(int i = 0;i < N;i++)pre[i] = -1,dp[i] = -INF; sort(v,v+n); dp[0] = 0; //和01背包类似,因为是恰好装满,其他只要赋上负无穷 for(int i = 0;i < n;i++){ for(int j = m;j >= v[i];j--){ if(dp[j] <= dp[j-v[i]]+1){ dp[j] = dp[j-v[i]]+1; ans[j] = v[i]; pre[j] = j - v[i]; } } } if(dp[m] <= 0) cout<<"No Solution"; else p(m); cout<<endl; return 0; }
如有错误或遗漏,请私聊下UP,ths
相关文章推荐
- L3-001. 凑零钱 01背包 满包问题+记录路径
- PAT L3-001 凑零钱(01背包(布尔背包)+记录路径)
- PAT L3-001. 凑零钱((背包&路径记录)
- CCCC 题目集 L3 001 凑零钱 【背包 + 记录路径 + 思维】
- PAT L3-001. 凑零钱(背包&路径记录)
- L3-001. 凑零钱(背包dp,输出路径)
- PAT -天梯赛 L3-001 凑零钱(01背包问题)
- L3-001. 凑零钱 (01背包)@
- 01满包加记录最小路劲 L3-001. 凑零钱
- L3-001. 凑零钱 (背包输出路径)
- L3-001. 凑零钱_动规_2018_2_22
- 2017百度之星资格赛:1004. 度度熊的午饭时光(01背包+记录路径)
- L3-001. 凑零钱
- ACM天梯赛 L3-001. 凑零钱
- 【团体程序设计天梯赛-练习集L3-015】球队“食物链”【状压dp+路径记录】
- PAT L2-001. 紧急救援 Dijkstra+权值+路径记录
- L3-001. 凑零钱
- L3-001. 凑零钱
- 记录路径的01背包问题
- L3-001. 凑零钱【dp】