L3 001 湊零錢 30分

2021-10-10 18:05:19 字數 1288 閱讀 8049

輸入第一行給出兩個正整數:n(≤10​4​​)是硬幣的總個數,m(≤10​2​​)是韓梅梅要付的款額。第二行給出 n 枚硬幣的正整數面值。數字間以空格分隔。

在一行中輸出硬幣的面值 v​1​​≤v​2​​≤⋯≤v​k​​,滿足條件 v​1​​+v​2​​+...+v​k​​=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 個空格分隔,行首尾不得有多餘空格。若...