韓梅梅喜歡滿宇宙到處逛街。現在她逛到了一家火星店里,發現這家店有個特別的規矩:你可以用任何星球的硬幣付錢,但是絕不找零,當然也不能欠債。韓梅梅手邊有 10000 枚來自各個星球的硬幣,需要請你幫她盤算一下,是否可能精確湊出要付的款額。
輸入格式:
輸入第一行給出兩個正整數:N(≤10000)是硬幣的總個數,M(≤100)是韓梅梅要付的款額。第二行給出 N 枚硬幣的正整數面值。數字間以空格分隔。
輸出格式:
在一行中輸出硬幣的面值 V1≤V2≤⋯≤Vk,滿足條件 V1+V2+...+Vk = M。數字間以 1 個空格分隔,行首尾不得有多余空格。若解不唯一,則輸出最小序列。若無解,則輸出 No Solution
。
輸入樣例 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<vector> #include<algorithm>
using namespace std; int s[10000]; int n,m; vector<int>p; bool flag=false; void dfs(int v,int sum){ if(sum>m||v>n){ return; } if(sum==m){ for(int i=0;i<p.size();i++){ if(i){ printf(" "); } printf("%d",p[i]); } printf("\n"); flag=true; return; } if(flag){ return; } p.push_back(s[v]); dfs(v+1,sum+s[v]); p.pop_back(); dfs(v+1,sum); } int main(){ scanf("%d %d",&n,&m); int sum=0; for(int i=0;i<n;i++){ scanf("%d",&s[i]); sum+=s[i]; } sort(s,s+n); if(sum<m){ printf("No Solution\n"); } else{ dfs(0,0); if(!flag) { printf("No Solution\n"); } } }