洛谷P2001 硬幣的面值

2021-10-06 10:19:56 字數 2487 閱讀 7666

其實這道題就按照題面意思直接模擬一下就好喇!

很顯然如果給定硬幣的最小值大於1則輸出"no answer!!!"因為這樣子就無法取到1這個面值了。

先證明一下這一點:如果目前狀態可取前 x

xx **,且當前取了乙個面額為 a

aa 的硬幣,要想構成前 x+a

x + a

x+a 的所有**,必須僅當 x≥a

−1

x \ge a - 1

x≥a−

1 時成立—>

證:若 x

1x < a - 1

x1, 則我們取最小的 x+1

x + 1

x+1,它必須由 x+1

−a

x + 1 - a

x+1−

a 得到,而 x

1x < a - 1

x1,故 x+1

−a

<

0x + 1 - a < 0

x+1−

a<

0,由於不存在小於0的狀態,故原命題成立。

假設當前狀態,前 i

ii 種硬幣已經用最小的硬幣數 ans

ansan

s 構成最大的可行** tot

totto

t ,那麼如果當前 tot

≥ai+

1−

1tot \ge a_ - 1

tot≥ai

+1​−

1,那麼就可以直接 i++

i + +

i++;否則累加,使 tot

=tot

+a

itot = tot + a_

tot=to

t+ai

​ 至 tot

≥ai+

1−

1tot \ge a_ - 1

tot≥ai

+1​−

1 , 同時每次 ans

ansans++

+++

+ 。因為我們在每一步都滿足 tot

≥ai+

1−

1tot \ge a_ - 1

tot≥ai

+1​−

1 , 所以每次 i++

i++i+

+ 時,我們都可以放心操作當前的 tot

+a

itot + a_

tot+ai

​ 操作。特別的,當 i

ii 等於1時,如果 tot

(=0)

−1

tot(=0) < a_ - 1

tot(=0

)​−1 , 即 a

1>

1a_ > 1

a1​>

1時,不能滿足條件,因而無答案,這裡解釋了第二段的顯然結論。

關於這個累加,由於資料範圍很大,我們很容易被卡(如都是1),所以我們先算出 tot

totto

t 加上多少個 aia_

ai​ 才能大於等於 ai+

1a_

ai+1

​,即個數 k=(

ai+1

−2−t

ot)÷

ai+1

k = (a_ - 2 - tot) \div a + 1

k=(ai+

1​−2

−tot

)÷ai

+1,再 tot

=tot

+k∗a

itot = tot + k * a_

tot=to

t+k∗

ai​,ans

=ans

+k

ans = ans + k

ans=an

s+k, 用 o(1)的時間解決了問題。同時我們把 an+

1a_

an+1

​ 賦值為 m

mm , 助於判停。

最後注意一點:如果 tot

totto

t 剛好等於 m−1

m - 1

m−1 ,並結束了迴圈,此時我們要在迴圈外輸出 ans

+1

ans + 1

ans+

1 , 以應對此特殊情況。

下面我來貼一下**—>

#include

#include

#define ll long long

#define inf 1023456789

using

namespace std;

ll n, m, a[

2000005

], ans, tot;

intmain()

a[n +1]

= m;

for(

int i =

1; i <= n; i++)}

}printf

("%lld\n"

,ans +1)

;return0;

}

洛谷P2001硬幣的面值

題目傳送門 真是個毒瘤題 一開始想這是乙個多重揹包板子題,於是不假思索打了上去,樣例沒過,再一看題,原來不是 又眼瞎了 於是再次認真讀題 很顯然我們可以發現 如果給定硬幣最小面額大於1,那麼就一定輸出no answer!因為首先 為1的就組成不了。接著思考,假設第i種硬幣已用最小硬幣數ans組成最大...

洛谷 P2708 硬幣翻轉

時間限制1.00s 記憶體限制125.00mb 從前有很多個硬幣擺在一行,有正面朝上的,也有背面朝上的。正面朝上的用1表示,背面朝上的用0表示。現在要求從這行的第乙個硬幣開始,將前若干個硬幣一起翻面,問如果要將所有硬幣翻到正面朝上,最少要進行這樣的操作多少次?乙個字串,由0和1組成,表示硬幣狀態 乙...

洛谷P1146 硬幣翻轉

時間限制 1.00s 記憶體限制 125.00mb 題目描述在桌面上有一排硬幣,共nn枚,每一枚硬幣均為正面朝上。現在要把所有的硬幣翻轉成反面朝上,規則是每次可翻轉任意n 1n 1枚硬幣 正面向上的被翻轉為反面向上,反之亦然 求乙個最短的操作序列 將每次翻轉n 1枚硬幣成為一次操作 輸入格式 乙個自...