动态规划之背包问题
来源:互联网 发布:全国姓名数据库 编辑:程序博客网 时间:2024/05/22 11:42
最近刷题遇到好几道背包问题,背包问题是动态规则中的一类体型,在考察算法的笔试中经常遇到。
关于背包问题,文章 背包问题九讲 中已经做了很多分析,这里就不再细述,建议好好看看这篇文章。
然而文章给了许多案例分析,却没有很好的练习。
说明:
1、本文目的不在于讲解背包问题的分析与讲解,而是收集了一些背包问题。希望学习者学习背包问题的时候能找到一些对应的题加以练习。
2、本文根据我是刷题中遇到的背包问题,会不定期更新内容。
0-1 背包问题
1、兑换奖券
http://hihocoder.com/problemset/problem/1038?sid=842443
基本解法:
#include <iostream>#include <algorithm>#include <vector>using namespace std;int main(){int i, j, n, m, need, val;while (cin >> n >> m){vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0));for (i = 1; i <= n; ++i){cin >> need >> val;for (j = 0; j <= m; ++j){if(j<need)dp[i][j] = dp[i - 1][j];elsedp[i][j] = max(dp[i - 1][j], dp[i - 1][j - need] + val);}}cout << dp[n][m] << endl;}return 0;}
#include <iostream>#include <algorithm>#include <vector>using namespace std;int main(){int i, j, n, m, need, val;while (cin >> n >> m){vector<int> dp(m + 1, 0);for (i = 0; i < n; ++i){cin >> need >> val;for (j = m; j >= need; --j)dp[j] = max(dp[j], dp[j - need] + val);}cout << dp[m] << endl;}return 0;}
如果要输出最优方案,增加一个state状态数组,修改代码如下:
#include <iostream>#include <algorithm>#include <vector>using namespace std;int main(){int i, j, n, m, need, val;while (cin >> n >> m){vector<int> dp(m + 1, 0), needs(n), vals(n);vector<vector<int>> state(n, vector<int>(m + 1, 0));for (i = 0; i < n; ++i){cin >> need >> val;needs[i] = need;vals[i] = val;for (j = m; j >= need; --j){if (dp[j] < dp[j - need] + val){dp[j] = dp[j - need] + val;state[i][j] = 1;}}}cout << dp[m] << endl;i = n;j = m;while (--i >= 0){if (state[i][j] == 1){cout << needs[i] << " ";j -= vals[i];}}}return 0;}
2、和为M的组合的个数(求方案数)
https://nanti.jisuanke.com/t/310
在N个数中找出其和为M的若干个数。先读入正整数N(1< N< 100)和M(1< M< 10000), 再读入N个正数(可以有相同的数字,每个数字均在1000以内), 在这N个数中找出若干个数, 使它们的和是M, 把满足条件的数字组合都找出来以统计组合的个数,输出组合的个数(不考虑组合是否相同)
#include <iostream>#include <vector>using namespace std;int main(){int n, m, coin;cin >> n >> m;vector<int> dp(m + 1, 0);dp[0] = 1;for (int i = 1; i <= n; ++i){cin >> coin;for (int j = m; j >=coin; --j)dp[j] += dp[j - coin];}cout << dp[m] << endl;return 0;}
完全背包问题
1、兑换奖券
http://hihocoder.com/problemset/problem/1043?sid=842590
#include <iostream>#include <algorithm>#include <vector>using namespace std;int main(){int i, j, n, m, need, val;while (cin >> n >> m){vector<int> dp(m + 1, 0);for (i = 0; i < n; ++i){cin >> need >> val;for (int j = need; j <= m; ++j)dp[j] = max(dp[j], dp[j - need] + val);}cout << dp[m] << endl;}return 0;}
2、换零钱(求方案数)
http://www.nowcoder.com/practice/185dc37412de446bbfff6bd21e4356ec
有一个数组changes,changes中所有的值都为正数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,对于一个给定值x,计算组成这个值的方案数。
int countWays(vector<int> changes, int n, int x) { int coin; vector<int> dp(x + 1, 0); dp[0] = 1; for (int i = 0; i < n; ++i) { coin=changes[i]; for (int j = coin; j <=x; ++j) dp[j] += dp[j - coin]; } return dp[x]; }
3、换零钱(求最少硬币数)
https://leetcode.com/problems/coin-change/
分组背包问题
不超过N元钱:https://nanti.jisuanke.com/t/256
题解:http://blog.csdn.net/zmq570235977/article/details/52354503
泛化物品
提升英雄: http://hihocoder.com/problemset/problem/1091
题解:http://blog.csdn.net/zmq570235977/article/details/52151096
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 动态规划之背包问题
- 2013-08-10:160-Intersection of Two Linked Lists
- 【HDU4747】【JZOJ4680】自然数
- AOS 自动生成代码(四) Controller生成
- http协议(模拟http请求,http与https的区别)
- 10131越大越聪明
- 动态规划之背包问题
- eclipse代码分析(code analysis)报错
- [HDU 5821] Ball (贪心)
- 在LINUX命令行中管理 Wifi 连接
- 第三方登陆,分享以及短信验证码
- 哈佛学生是如何度过大学4年的
- zbud的疑问???
- Java中的private、protected、public和default的区别
- java代码怎么设置控件的外边距