其實這道題就按照題面意思直接模擬一下就好喇!
很顯然如果給定硬幣的最小值大於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 #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; } 題目傳送門 真是個毒瘤題 一開始想這是乙個多重揹包板子題,於是不假思索打了上去,樣例沒過,再一看題,原來不是 又眼瞎了 於是再次認真讀題 很顯然我們可以發現 如果給定硬幣最小面額大於1,那麼就一定輸出no answer!因為首先 為1的就組成不了。接著思考,假設第i種硬幣已用最小硬幣數ans組成最大... 時間限制1.00s 記憶體限制125.00mb 從前有很多個硬幣擺在一行,有正面朝上的,也有背面朝上的。正面朝上的用1表示,背面朝上的用0表示。現在要求從這行的第乙個硬幣開始,將前若干個硬幣一起翻面,問如果要將所有硬幣翻到正面朝上,最少要進行這樣的操作多少次?乙個字串,由0和1組成,表示硬幣狀態 乙... 時間限制 1.00s 記憶體限制 125.00mb 題目描述在桌面上有一排硬幣,共nn枚,每一枚硬幣均為正面朝上。現在要把所有的硬幣翻轉成反面朝上,規則是每次可翻轉任意n 1n 1枚硬幣 正面向上的被翻轉為反面向上,反之亦然 求乙個最短的操作序列 將每次翻轉n 1枚硬幣成為一次操作 輸入格式 乙個自...#include
洛谷P2001硬幣的面值
洛谷 P2708 硬幣翻轉
洛谷P1146 硬幣翻轉