動態規劃 硬幣 POJ

2021-08-01 20:31:57 字數 2270 閱讀 7574

總時間限制: 1000ms 記憶體限制: 262144kb

描述 太空人bob有一天來到火星上,他有收集硬幣的習慣。於是他將火星上所有面值的硬幣都收集起來了,一共有n種,每種只有乙個:面值分別為a1,a2… an。 bob在機場看到了乙個特別喜歡的禮物,想買來送給朋友alice,這個禮物的**是x元。bob很想知道為了買這個禮物他的哪些硬幣是必須被使用的,即bob必須放棄收集好的哪些硬幣種類。飛機場不提供找零,只接受恰好x元。

輸入 第一行包含兩個正整數n和x。(1 <= n <= 200, 1 <= x <= 10000)

第二行從小到大為n個正整數a1, a2, a3 … an (1 <= ai <= x)

輸出 第一行是乙個整數,即有多少種硬幣是必須被使用的。

第二行是這些必須使用的硬幣的面值(從小到大排列)。

樣例輸入

5 18

1 2 3 5 10

樣例輸出

2 5 10

本篇文章收錄了兩種不同的**思路

分別來自@beiyu-oi和@iamxym

說是兩種不同**,其實整體的核心思路相同.不過是乙個完全採用了動規的實現方法,另乙個結合了遞迴;

核心思路:首先求出所有硬幣組合成總價值為j的方法總數(0 <= p <= x);然後考慮遞推關係式,遍歷每乙個硬幣,如果硬幣必須被使用,則總價值為x的方法中,每一種都含有這個硬幣,若這個硬幣的價值為i,則總價值為x的組合方法中,不含有這個硬幣的方法數目為0;總價值為x - i的組合方法中,含有這個硬幣的方法數目也為0;這兩個判斷條件任選其一;

如何求出所有硬幣組合成總價值為i的方法總數呢?

開陣列kinds[10010],下標為總價值;

每一次輸入乙個硬幣就更新一次kinds陣列,輸入硬幣後kinds[j] 有兩種選擇:不含有這個硬幣和含有;對於不含有的方法總數等於輸入硬幣前的kinds[j],含有這個硬幣大的方法數目等於輸入硬幣前的kinds[j - value](value為輸入硬幣的面值)

既然每次更新kinds[j]都要用到更新前的kinds[j - value],那就從後向前更新;

話不多說,上**!

方法一:來自@beiyu-oi

/*

*  程式名: 硬幣 ***/

#include

#include

#include

using namespace std;

int kinds[10010]; // 儲存總價值為p的方法總數;

int calc(int allvalue, int nowvalue) // 總價值為allvalue

//不含有這一枚面值為nowvalue的硬幣的方法數目;

int main()

int finalcoin[210];

int cntcoin = 0;

/*遍歷每一枚硬幣,

若總價值為x且不含這枚硬幣的方法數目為0,則必須含有這枚硬幣*/

for (int i = 1; i <= n; ++i)

if (calc(x, values[i]) == 0)

finalcoin[cntcoin++] = values[i];

cout << cntcoin << endl;

if (!cntcoin)

cout << endl;

else

for (int i = 0; i < cntcoin; ++i)

cout << finalcoin[i] << " ";

return 0; }

方法二,來自@iamxym /*

* 硬幣 方法二**/

#include

#include

#include

using namespace std;

int kinds[10010]; // 總價值為j的硬幣組合種數

int mykinds[10010]; // 每輸入一次硬幣更新一次

// 表示不含這個硬幣,價值為j的硬幣組合種數目

//若mykinds[x]為0,則必須包含這一枚硬幣

int number[210];//必須包含的硬幣,其中num[0]表示必須包含的硬幣數目;

int main()

/*逐個檢視每乙個硬幣是不是必須的*/

for (int i = 1; i <= n; ++i)

cout << number[0] << endl;

if (number[0] == 0)

cout << endl;

else

return 0;

}

動態規劃 硬幣問題

這是乙個固定重點的最長路和最短路問題,可用動態規劃問題來求解 代表硬幣總值,n代表硬幣總數,v陣列儲存硬幣各個面值,d代表從i出發到結點0的路徑的最長路徑長度或最短路徑長度 vis代表是否訪問過該結點 int n,s,v maxn d maxn vis maxn int dpmax int s re...

動態規劃 硬幣問題

2013 07 11 03 17 5610人閱讀收藏 舉報 演算法和資料結構學習 79 最少硬幣問題 假設有3種不同的硬幣,幣值分別是coinvalue 每一種硬幣的數量是有限的,分別是coinnum 給定乙個數值target 18,找出一種硬幣數最少的方法,輸出最少的硬幣數。思路 動態規劃。問題定...

動態規劃 分硬幣

解題心得 1 主要是找到狀態和狀態轉移方程,將大的問題縮小,一步步擴大得到最後的最優解。2 和最長上公升子串行相比,此問題不過是單位長度1變成了硬幣的分值,所以將大於或小於改為value的幾個值 3 可以想推出前面幾項來得出最後的狀態轉移公式。上面是在網上看到的一篇好文章,裡面有乙個湊硬幣的問題 如...