輸入第一行給出兩個正整數:n(≤104)是硬幣的總個數,m(≤102)是韓梅梅要付的款額。第二行給出 n 枚硬幣的正整數面值。數字間以空格分隔。
在一行中輸出硬幣的面值 v1≤v2≤⋯≤vk,滿足條件 v1+v2+...+vk=m。數字間以 1 個空格分隔,行首尾不得有多餘空格。若解不唯一,則輸出最小序列。若無解,則輸出no solution
。
注:我們說序列比「小」,是指存在 k≥1 使得 a[i]=b[i] 對所有 i分析:這個題可以使用回溯和揹包兩種解法
本題使用回溯,不需要特別困難的剪枝就可以過。。。但是先判斷一下所有硬幣的面值總和是不是大於付款金額,否則最後乙個測試點會超時。
#includeusing namespace std;
int f,n,m;
int a[10010];
int vis[10010];
vectortemp;
void dfs(int sum)
sort(a+1,a+1+n); //將硬幣按面值從小到大排序,確保最後找出來的序列是按從小到大排的
if(s本題屬於01揹包,只不過就是需要把價值也看出重量而已,這樣如果對應容量的揹包裡若可以裝東西,那麼該揹包裡物品價值一定是揹包容量大小。
難點在於如果輸出最小序列
01揹包問題,因為要輸出從小到大的排列,可以先把硬幣面額從大到小排列,然後用bool型別的choice[i][j]陣列dp[i][j]是否選取,如果選取了就令choice為true;然後進行01揹包問題求解,如果最後求解的結果不是恰好等於所需要的價值的,就輸出no soultion,否則從choice[i][j]判斷選取的情況,i從n到1表示從後往前看第i個物品的選取情況,j從m到0表示從容量m到0是否選取(j = j – w[i]),把選取情況壓入arr陣列中,最後輸出arr陣列
參考了柳婼大神的**。
#include #include #include #includeusing namespace std;
int dp[100];
int w[100];
bool choice[100][100];
int cmp1(int a, int b)
int main() }}
for(int i=1;i<=n;i++)
index--;
}for(int i = 0; i < arr.size(); i++)
}return 0;
}
L3 001 湊零錢 (30 分)
輸入第一行給出兩個正整數 n 10 4 是硬幣的總個數,m 10 2 是韓梅梅要付的款額。第二行給出 n 枚硬幣的正整數面值。數字間以空格分隔。在一行中輸出硬幣的面值 v 1 v 2 v k 滿足條件 v 1 v 2 v k m。數字間以 1 個空格分隔,行首尾不得有多餘空格。若解不唯一,則輸出最小...
L3 001 湊零錢 30 分
題目鏈結 這種選和不選的題最好用遞迴做了,但是需要剪枝,然後就是對特殊情況的考慮,不然會超時。注意當陣列中所有數的和加起來都達不到目標值,就沒必要搜尋了,直接輸出無解 include using namespace std const int maxn 1e4 5 const int maxx 1e...
L3 001 湊零錢 30 分
輸入格式 輸入第一行給出兩個正整數 n 10 4 是硬幣的總個數,m 10 2 是韓梅梅要付的款額。第二行給出 n 枚硬幣的正整數面值。數字間以空格分隔。輸出格式 在一行中輸出硬幣的面值 v 1 v 2 v k 滿足條件 v 1 v 2 v k m。數字間以 1 個空格分隔,行首尾不得有多餘空格。若...