題目連結: https://zerojudge.tw/ShowProblem?problemid=f815

# 解題思路

我們可以透過先假設一個結果,再判斷該結果是否為最佳,
假設錢的總數足夠達到該結果,就將結果往上調一等,
若不足夠,則往下調整一等,直到最終結果是符合結果中的最大值。

但是,依序的搜索對於這題而言太過緩慢,又因為調整的結果情況為一次一次的,類似於查找已排序序列的結果
因此,我們這題可以透過對答案二分搜的方式,將答案逼近到我們想要的目標結果。

(這題的程式碼以左閉右開的形式撰寫)

# 程式碼

#include <iostream>
using namespace std;
#define int long long 
int lv[20005],n;
int gold(int m) // 計算到等級 m 需要的金幣
{
    int sum=0;
    for(int i=0;i<n;i++)
        if (lv[i]<m)   // 如果士兵等級 < m
            sum += (lv[i]-m)*(lv[i]-m);  // 計算需要的花費後加總
    return sum;
}
signed main(){
    int c,L=1,R=20000005,m; // 左閉,右開
    cin >> n >> c;
    for(int i=0;i<n;i++)
        cin >> lv[i];
    while(L<R)
    {
        m = (L+R)/2;      // 預期的等級 m
        if (gold(m)>c)   // 需要的金幣 > 預算
            R = m;  // 調整 R
        else
            L = m+1;  // 調整 L
    }
    cout << R-1 << endl; 
    return 0;
}
更新於 閱讀次數

用實際行動犒賞爆肝的我😀

Zrn Ye LinePay

LinePay