【PAT Advanced Level】1068. Find More Coins (30)
来源:互联网 发布:blooming服装 知乎 编辑:程序博客网 时间:2024/06/05 04:30
最近在学习动态规划,PAT中的这一题就是一个典型的dp问题。
这一题和01背包问题很类似,M相当于背包问题中的背包容量,硬币面值相当于每件物品的重量,背包问题中要求物品价值最大,这里要求物品总重(面值和)等于M,从可选方案中选择最优的是根据给定的比较方法。
我们解决问题的难点:如何选择出最小的序列?
首先来看递归式:L(i, j)表示在前i号硬币中选择,并且总价值小于等于j的序列的最大面值和。这里我们不要求等于j,只要尽量接近j就可以了。a[i]是i号硬币的面值,则递归式如下:
L(i, j) = 0i == 0 || j == 0
= L[i - 1, j] a[i] > j
= max(L(i - 1, j - a[i]) + a[i], L(i - 1, j))a[i] <= j
自底向上填表之后,回溯一遍就可以得到所得序列。
但是想要保证序列“最小”,就必须将原面值递减排序。在回溯中每次遇到L(i - 1, j - a[i]) + a[i]这种情况,就决定选择a[i],因为此时a[i]总是最小的。
//类似于01背包的DP//降序排列是关键!!!#include <iostream>#include <vector>#include <algorithm>#include <fstream>using namespace std;int N, M;vector<int> v;vector<vector<int>> l;void dp(){for(int i = 1; i <= N; i++){for(int j = 1; j <= M; j++){if(v[i] > j)l[i][j] = l[i - 1][j];else l[i][j] = l[i - 1][j - v[i]] + v[i] > l[i - 1][j] ? l[i - 1][j - v[i]] + v[i] : l[i - 1][j];}}if(l[N][M] != M){cout<<"No Solution"<<endl;return;}//回溯输出选取的序列int j = M;int i = N;//cout<<" ";while (j > 0){if(l[i][j] == l[i - 1][j - v[i]] + v[i]){cout<<v[i];j -= v[i];i -= 1;if(j != 0) cout<<" ";}else{i -= 1;}}cout<<endl;}bool cmp(const int &a, const int &b){return a > b;}int main(){//fstream cin("a.txt");cin>>N>>M;v.push_back(0);for(int i = 0; i < N; i++){int tmp;cin>>tmp;v.push_back(tmp);}sort(v.begin() + 1, v.end(), cmp);for(int i = 0; i <= N; i++){vector<int> tmp;for(int j = 0; j <= M; j++)tmp.push_back(0);l.push_back(tmp);}dp();}
- 【PAT Advanced Level】1068. Find More Coins (30)
- 【PAT】【Advanced Level】1068. Find More Coins (30)
- PAT (Advanced Level) Practise 1068 Find More Coins (30)
- PAT (Advanced Level) Practise 1068 Find More Coins (30)
- PAT (Advanced Level) 1068. Find More Coins (30) DFS+剪枝 或 动态规划
- 1068. Find More Coins (30)【背包】——PAT (Advanced Level) Practise
- Pat(Advanced Level)Practice--1068(Find More Coins)
- Pat(Advanced Level)Practice--1048(Find Coins)
- 【PAT】【Advanced Level】1048. Find Coins (25)
- PAT A 1068. Find More Coins (30)
- pat 1068. Find More Coins (30)
- PAT 1068. Find More Coins (30)
- 【PAT】1068. Find More Coins (30)
- pat 1068. Find More Coins (30)
- PAT(A) - 1068. Find More Coins (30)
- PAT甲级1068. Find More Coins (30)
- pat 1068. Find More Coins (30)
- 【PAT甲级】1068. Find More Coins (30)
- 变结构垂直俯冲攻击制导律(源代码)
- 具有角度和时间约束的导弹最优全弹道设计(源代码)
- Lucene学习总结之二:Lucene的总体架构
- fcntl的使用
- gen_server模块
- 【PAT Advanced Level】1068. Find More Coins (30)
- Lucene学习总结之三:Lucene的索引文件格式(1)
- Java Precondition类
- 四元数与欧拉角间的转换(源代码)
- OPENFIRE+MYSQL5.6安装中遇见Specified key was too long; max key length is 767 bytes openfire处理办法
- 第十周上机实践------乘法口诀
- fzu Problem 2128 最长子串 (注意strstr函数的使用)
- connect函数返回值
- shell 十三问: