總時間限制: 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 可以想推出前面幾項來得出最後的狀態轉移公式。上面是在網上看到的一篇好文章,裡面有乙個湊硬幣的問題 如...