題目:
description
小蛇是金融部部長。最近她決定製造一系列新的貨幣。假設她要製造的貨幣的面值為x1,x2,x3… 那麼x1必須為1,xb必須為xa的正整數倍(b>a)。例如1,5,125,250就是一組合法的硬幣序列,而1,5,100,125就不是。不知從哪一天開始,可愛的蛇愛上了一種萌物——兔紙!從此,小蛇便走上了遇上兔紙娃娃就買的不歸路。某天,小蛇看到了n只可愛的兔紙,假設這n 只兔紙的價錢分別是a1,a2…an。現在小蛇想知道,在哪一組合法的硬幣序列下,買這n只兔紙所需要的硬幣數最少。買兔紙時不能找零,1<=n<=50, 1<=ai<=100,000
input
第一行,乙個整數n,表示兔紙的個數
第二行,n個用空格隔開的整數,分別為n只兔紙的價錢
output
一行,乙個整數,表示最少付的錢幣數。
sample input
225 102
sample output
4
hint
樣例解釋:共有兩隻兔紙,價錢分別為25和102。現在小蛇構造1,25,100這樣一組硬幣序列,那麼付第一只兔紙只需要乙個面值為25的硬幣,第二隻兔紙需要乙個面值為100的硬幣和兩個面值為1的硬幣,總共兩隻兔紙需要付4個硬幣。這也是所有方案中最少所需要付的硬幣數。
這是乙個貪心+動態規劃問題
關於貪心比較好理解,在給定硬幣序列的情況下,盡量使最大的硬幣使用最多,然後再盡量使第二大的硬幣使用最多,等等。。。
這種貪心策略,只在本題條件下成立,對於一般的硬幣序列就不一定了。
動態規劃就比較有趣了。
用dp[i]表示在最大的硬幣為i的情況下,最少需要付的硬幣數
那麼dp[j]是滿足i|j的所有i中,f(i,j)的最小值
其中,f(i,j)表示的是最大硬幣為j,第二大的硬幣為i時,最少需要付的硬幣數,可以根據dp[i]直接求出來。
這樣就得到了遞推式,可以動態規劃了,不過超時了。
於是上面的演算法還可以優化:
dp[j]是滿足i|j的所有i中,f(i,j)的最小值,這一點無疑是對的,但是還不夠簡單。
實際上,dp[j]是滿足j=i*p(p為任意素數)的所有i中,f(i,j)的最小值
這樣,計算可以變快,不過需要預先給出素數表。
我用的方法是篩法打表,把素數按順序存到pri陣列中
**:
#includeusing namespace
std;
int num[
50], dp[
100001
], prime[
100001
], pri[
10000
];int
main
()for
(int i =
1; i <= m; i++)prime[i]=1
;for
(int i =
2; i <= m; i++)
if(prime[i])
for(
int i =
2; i <= m; i++)dp[i]
=12345678
;for
(int i =
1; i <= m; i++)
} cout << result << endl;
return0;
}
BZOJ1002(找規律 大數)
time limit 1 sec memory limit 162 mb submit 2427 solved 1333 submit status 給定n n 100 程式設計計算有多少個不同的n輪狀病毒。第一行有1個正整數n。將程式設計計算出的不同的n輪狀病毒數輸出 316 題意 rt 思路 d...
bzoj4566 找相同字元
題意 給定兩個字串,從中各取乙個子串使之相同,有多少種取法。允許本質相同。解 建立廣義字尾自動機,對於每個串,分別統計cnt,之後每個點的cnt乘起來。記得開long long 1 include 2 include 3 include 4 5 typedef long long ll 6 cons...
BZOJ4264 小C找朋友
description 幼兒園裡有n個小c,兩個小c之間可能是朋友也可能不是。所有小c之間的朋友關係構成了乙個無向圖,這個無向圖中有m條邊。園長atm發現對於兩個 不同的 小ci和j,如果其他的所有小c要麼同時是i,j的朋友,要麼同時不是i,j朋友的話,這兩個小c就很有可能一起去吃飯,成為一對好友。...