1068. Find More Coins 解析

来源:互联网 发布:网络正常微信发不出去 编辑:程序博客网 时间:2024/06/07 03:09

这个大神算法很厉害 http://blog.csdn.net/tiantangrenjian/article/details/17334201

看了好久这个算法。转了好久才有点明白其中的味道。。

主要时明白这个两个二维数组的含义。横轴和纵轴所代表的意思。

注释了下程序 应该比较好看懂了。。


#include <iostream>#include <vector>#include <algorithm>#include <cstring>#define maxN 10010#define maxM 110using namespace std;vector <int> patch;int f[maxN][maxM];int has[maxN][maxM];int c[maxN];int n,m;bool cmp(int n1, int n2) {return n1 > n2;}int main() {cin >> n >> m;for (int i = 1; i <= n; i++) {scanf("%d", &c[i]);}sort(c + 1, c + n + 1, cmp);memset(f, 0, sizeof(f));memset(has, false, sizeof(has));//int sec;//加入当前硬币f[i - 1][j - c[i]] + c[i] 不加入硬币f[i-1][j]//i为硬币面额 j为当前最大和for (int i = 1; i <= n; i++) {//硬币面额for (int j = 1; j <= m; j++) {//总和if (j - c[i] < 0) { //当前能到的最大值j 比当前硬币还小 硬币不能用sec = 0;}else {sec = f[i - 1][j - c[i]] + c[i]; //加上当前硬币能够到达的最大值}if (sec >= f[i - 1][j]) {//加入硬币大has[i][j] = true;f[i][j] = sec;}else {f[i][j] = f[i - 1][j];}}}if (f[n][m] == m) {while (m) {//反向查询if (!has[n][m]) { //硬币从小往大查询 没有加入查询下一个n--;}else {//在队列里面patch.push_back(c[n]);m -= c[n];//减去该硬币大小查询m-c[n]时所需要的硬币n--;}}for (int i = 0; i < patch.size() - 1; i++) {cout << patch[i] << " ";}cout << patch[patch.size() - 1] << endl;}elsecout << "No Solution" << endl;return 0;}


0 0