【PTA】L3-001 凑零钱 (30分)

L3-001 凑零钱 (30分)

韩梅梅喜欢满宇宙到处逛街。现在她逛到了一家火星店里,发现这家店有个特别的规矩:你可以用任何星球的硬币付钱,但是绝不找零,当然也不能欠债。韩梅梅手边有 10​4​​ 枚来自各个星球的硬币,需要请你帮她盘算一下,是否可能精确凑出要付的款额。
输入格式:

输入第一行给出两个正整数:N(≤10​4​​)是硬币的总个数,M(≤10​2​​)是韩梅梅要付的款额。第二行给出 N 枚硬币的正整数面值。数字间以空格分隔。
输出格式:

在一行中输出硬币的面值 V​1​​≤V​2​​≤⋯≤V​k​​,满足条件 V​1​​+V​2​​+...+V​k​​=M。数字间以 1 个空格分隔,行首尾不得有多余空格。若解不唯一,则输出最小序列。若无解,则输出 No Solution。

注:我们说序列{ A[1],A[2],⋯ }比{ B[1],B[2],⋯ }“小”,是指存在 k≥1 使得 A[i]=B[i] 对所有 i<k 成立,并且 A[k]<B[k]。
输入样例 1:

8 9
5 9 8 7 2 3 4 1

输出样例 1:

1 3 5

输入样例 2:

4 8
7 2 4 3

输出样例 2:

No Solution

#include <iostream>
#include <bits/stdc++.h>

using namespace std;

int arr[10001];
int sum,n,m,t,flag;
int money[10001];
int book[10001];

bool compare(int a,int b){
    return a<b;
}

void dfs(int k){
    if(sum>m) return;
    if(sum==m){
        flag=1;
        printf("%d",money[0]);
        for(int i=1;i<t;i++){
            printf(" %d",money[i]);
        }
    }
    else{
        for(int i=k;i<n;i++){
            if(!book[i]&&!flag){
                book[i]=1;
                money[t++] = arr[i];
                sum +=arr[i];
                dfs(k+1);
                sum -=arr[i];
                money[--t] = 0;
                book[i]=0;

            }
        }
    }
}


int main()
{
    scanf("%d %d",&n,&m);
    int S=0;
    for(int i=0;i<n;i++){
        scanf("%d",&arr[i]);
        S+=arr[i];
    }
    if(S<m) printf("No Solution
");
    else{
        sort(arr,arr+n,compare);
        dfs(0);
        if(!flag){
            printf("No Solution
");
        }
    }
}
原文地址:https://www.cnblogs.com/Andre/p/12544187.html