码迷,mamicode.com
首页 > 其他好文 > 详细

pat 1068 动态规划/Fina More Conis

时间:2014-06-08 18:49:44      阅读:432      评论:0      收藏:0      [点我收藏+]

标签:c   style   class   blog   code   a   

1068. Find More Coins (30)

Eva loves to collect coins from all over the universe, including some other planets like Mars. One day she visited a universal shopping mall which could accept all kinds of coins as payments. However, there was a special requirement of the payment: for each bill, she must pay the exact amount. Since she has as many as 104 coins with her, she definitely needs your help. You are supposed to tell her, for any given amount of money, whether or not she can find some coins to pay for it.

Input Specification:M

Each input file contains one test case. For each case, the first line contains 2 positive numbers: N (<=104, the total number of coins) and M(<=102, the amount of money Eva has to pay). The second line contains N face values of the coins, which are all positive numbers. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print in one line the face values V1 <= V2 <= ... <= Vk such that V1 + V2 + ... + Vk = M. All the numbers must be separated by a space, and there must be no extra space at the end of the line. If such a solution is not unique, output the smallest sequence. If there is no solution, output "No Solution" instead.

Note: sequence {A[1], A[2], ...} is said to be "smaller" than sequence {B[1], B[2], ...} if there exists k >= 1 such that A[i]=B[i] for all i < k, and A[k] < B[k].

Sample Input 1:
8 9
5 9 8 7 2 3 4 1
Sample Output 1:
1 3 5
Sample Input 2:
4 8
7 2 4 3
Sample Output 2:
No Solution

自己的动态规划有些弱,一直在想办法提高,在遇到这道题目后,第一时间知道肯定要用DP(这里的要求与经典的背包问题很相似),在尝试着去做的过程中,回忆着DP的应用场景,结合这道题目的特殊需求,在过程中进行设计;
先回顾下动态规划问题的几个要素:最优子结构、子问题重叠、边界与子问题的独立性;这里我们可以看到面值M通过选择若干小面值的组合来组成,假定每个面值是value[i],我们的问题变成了对于每个阶段的i-th coin,求得M-value[i](选取了i-th coin)/M9未选取i-th coin)的最佳组合问题,而这个问题与原问题是完全独立的,且本质完全相同,即子结构问题,并且每一步的问题都是重叠的;至于边界,在没有一枚硬币被选中的时候,支付金额为0,之后的问题可以依次累计。
【关于动态规划的帮助理解,有一篇讲解金矿问题的很形象直观的博客讲得很好】http://www.cnblogs.com/sdjl/articles/1274312.html
这里的特殊地方在于除了选取到面值恰好相同的结果外,还要求在有多个解的情况下,能够选出顺序的value最小的一种组合,经过考虑后,我采取的是对value进行高->低的排序,之后进行动态规划的求解,并单独设置标志,由于要得的是value尽可能小,因此在后边进行选择的只要加入后支付值>或者是=都以最新的value组合为准,这样就保证了相同的组合小面值的被选取。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <vector>
using namespace std;
int pay[10010][110];
int flag[10010][110];//0:heritate from the last circle;1:add the current value
int value[10010];
vector<int> v;
bool cmp(int a, int b){
    return a > b;
}
int main(){
    int N, M,i,max=0,temp1,temp2,j,temp;
    int row, col;
    scanf("%d%d", &N, &M);
    for (i = 1; i <= N; i++){
        scanf("%d", &value[i]);
    }
    sort(value+1, value + N + 1, cmp);
    for (i = 1; i <= N; i++){
        //temp1:the last row,corresponding value
        //temp2:add the new value
        max += value[i];//the upper bound
        temp = max > M ? M : max;
        for (j = value[i]; j <= temp; j++){
            temp1 = pay[i - 1][j];
            temp2 = pay[i - 1][j - value[i]] + value[i];
            if (temp1 <= temp2){//add
                flag[i][j] = i;
                pay[i][j] = temp2;
            }
            else
                pay[i][j] = temp1;
        }
    }
    if (pay[N][M] == M){//succeed to find the proper value
        row = N, col = M;
        while (pay[row][col] != value[row]){
            if (flag[row][col] != 0){
                v.push_back(value[row]);
                col = col - value[row];
                row--;
            }
                 
            else{
                row--;
            }
        }
        v.push_back(value[row]);
        for (i = 0; i < v.size()-1; i++)
            printf("%d ", v[i]);
        printf("%d", v[i]);
    }
    else{
        printf("No Solution");
    }
    system("pause");
    return 0;
}

  

 

pat 1068 动态规划/Fina More Conis,布布扣,bubuko.com

pat 1068 动态规划/Fina More Conis

标签:c   style   class   blog   code   a   

原文地址:http://www.cnblogs.com/KarayLee/p/3776206.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!