7_6_M题 The Values You Can Make题解[Codeforces 687C](DP)
2016-07-10 22:36
501 查看
题目链接
设硬币的面值为coin[i] 则转移方程为
dp[i][k][s]=dp[i−1][k][s]∣dp[i−1][k−coin[i]][s]∣dp[i−1][k−coin[i]][s−coin[i]]
初始化 dp[0][0][0]=true
简单题意
有n枚硬币,面值不尽相同,要给出价值和为k的硬币,问用价值和为k的硬币能组合出多少种不同的面值?思路
动规 dp[i][k][s] 代表前 i 枚硬币中,价值和为 k 的子集能否组合出价值为 s 面值。设硬币的面值为coin[i] 则转移方程为
dp[i][k][s]=dp[i−1][k][s]∣dp[i−1][k−coin[i]][s]∣dp[i−1][k−coin[i]][s−coin[i]]
初始化 dp[0][0][0]=true
代码
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <queue> using namespace std; const int maxn = 5e2+5; bool dp[2][maxn][maxn]; int coin[maxn]; queue<int> ans; int main(){ int n ,m; scanf("%d %d", &n,&m); for(int i = 1 ; i <= n ; i ++) scanf("%d", coin + i); dp[0][0][0] = 1; for(int i = 1 ; i <= n ; i ++){ for(int j = 0 ; j <= m ; j ++){ for(int k = 0 ; k <= j ; k ++){ dp[i%2][j][k] |= dp[(i-1)%2][j][k]; if(j >= coin[i]) dp[i%2][j][k] |= dp[(i-1)%2][j-coin[i]][k]; if(k >= coin[i]) dp[i%2][j][k] |= dp[(i-1)%2][j-coin[i]][k-coin[i]]; } } } for(int i = 0 ; i <= m ; i ++) if(dp[n%2][m][i]) ans.push(i); printf("%d\n", ans.size()); while(!ans.empty()){ printf("%d ",ans.front()); ans.pop(); } return 0; }
相关文章推荐
- ui布局
- ui
- uva 1626 Brackets sequence
- .Net Core开发环境Build
- 1041. Be Unique (20)
- java rabbitmq MessageQueue 使用第一章
- 3、easyUI-创建 CRUD可创建展开行明细编辑dataGrid(表格)
- @GeneratedValue
- hibernate id 生成策略
- UITableView优化方案
- iOS中自定义输入文本框的cell(UITextFieldCell)的使用技巧
- MathJax basic tutorial and quick reference
- java中String、StringBuffer、StringBuilder的区别
- String StringBuilder StringBuffer 对比 总结得非常好
- hdu 4296 Buildings 贪心 解题报告
- EasyUI小图标设置
- Android线程的三种用法和子线程更新UI两种用法
- UE中使用正则表达式的一些技巧
- Building an MFC project for a non-Unicode character set is deprecated
- GPUImage使用