XJTUOJ 1023 JM的祖傳零錢箱

2022-04-14 02:36:19 字數 1312 閱讀 7391

jm的太爺爺的太爺爺的太爺爺……的太爺爺喜歡攢零錢,並把攢零錢作為祖訓傳承至今,現在已經攢了整整一箱子的硬幣,jm清點了一下發現箱子裡一共有\(n\)枚硬幣。眾所周知,古代的錢幣放到現在都很值錢,所以這些硬幣的價值並不相同。不過,由於寒域爺施了石志魔法,這些硬幣的價值都是\(2\)的冪次。也就是說,對於任意的第\(i\)枚硬幣,其價值\(a_i\)一定滿足\(a_i=2^d\),其中\(d\)是某個非負整數。

現在,石樂志的jm想拿這些硬幣去買菜,他有\(q\)種想買的菜。因為石樂志,jm認為硬幣的價值並不重要,而硬幣的數量是最重要的。所以在買菜之前,他想事先知道,對於每種**為\(b_j\)的菜,他最少需要用掉多少枚硬幣才能將其買下。另外,由於jm有強迫症,他不希望他在買菜的時候還需要找零。

他希望你幫他分別計算買這\(q\)種菜的所需硬幣數。注意,是分別計算,每種菜的求解之間是互相獨立的。

第一行兩個正整數\(n\)和\(q\),表示jm的硬幣數和jm想買的菜的種類數。

接下來一行\(n\)個正整數\(a_i\),表示每個硬幣的價值。輸入保證\(a_i=2^d\),其中\(d\)是某個非負整數。

接下來\(q\)行,每行乙個正整數\(b_j\),表示每種菜的**。

輸出\(q\)行,每行乙個正整數,表示買下每種菜所需的最少硬幣個數。如果無論如何也無法湊齊**(注意不能找零),則輸出\(-1\)。

\(1\leq n,q \leq 2*10^5\)

\(1\leq a_i,b_j \leq 2*10^9\)

儲存:我們可以令\(a[i]\)表示面值為\(2^i\)的硬幣有多少枚。

這是一道貪心題,對於每乙個\(x\),我們從2的高次冪往低次掃,能取就盡量取完。比如現在硬幣面額為\(2^i\),所取的數量\(t\)應為滿足\(t\leq a[i]\)且\(t*2^i\leq x\) 的最大值。

如果這樣取最終能使x歸零,那麼有解,且最優取法如上;否則無解。

為什麼呢?因為低次冪可以拼成高次冪,而高次冪無法拆成低次冪。所以我們優先把高次冪取掉,既減少了所用硬幣數量,又留下更多靈活的小面額給接下來的步驟。(感性理解一下)

注意:題目所給的資料範圍很接近int的最大值,小心溢位。

#include#include#includeusing namespace std;

int a[30];

int main()

a[t]++;

} for(i=1;i<=m;i++)

if(!x) printf("%d\n",ans);

else printf("-1\n");

} return 0;

}

換零錢的演算法

問題來自sicp,描述如下 現在若干紙幣,想要兌換成硬幣。硬幣面值有1,5,10,25,50分的硬幣。什麼,沒有25分的,我說的是美元。問有多少種組合方式 這是介紹線性遞迴這個概念的時候的乙個例子,很有意思。演算法嘛,很樸素啊,其主要思想如下 scheme的 就不貼上來了,太簡單太抽象。我們還是用c...

零錢有限制和沒有限制的找零錢問題

int k count 0 long long k sum 1 while k sum n 小於且最接近n的2的k次冪的整數 vector long arr k count,0 把相應的零錢存入陣列中 k sum 1 arr 0 1 for int i 1 i k count i 要列舉的動態規劃的...

零錢組合的幾種解法

存在這樣乙個陣列,int arr 100 裡面是各種零錢的金額,我們還假設每一種零錢都有無數種,請問這些金錢組成乙個特定面額數值的組合數。比如 要組成1元,則情況為 5 10 25 1 0 0 0 10 0 1 0 0 1 0 0 5 2 0 0 0 一共四種可能,我們可以看到,如果只有五元的時候,...