XJOI 3601 技能(貪心 二分)

2022-05-05 20:42:08 字數 2310 閱讀 8055

題目描述:

有乙個oier,他有n

個演算法技能,每個技能有乙個水平值,每個技能的水平上限都是a

,設這個oier有cnt

個技能達到了a

, 設所有水平值的最小值為mi

,那麼這個oier的戰鬥力為cnt×cf+mi×cm

,現在這個oier準備去提公升自己的技能,他有m

次提公升的機會,每次提公升可以選擇某乙個技能給水平值加1,如何分配這些提公升的機會,來使得自己的戰鬥力總值最大?

輸入格式:

第一行輸入5

個整數,n,a,cf,cm,m

第二行輸入n

個整數,表示每個技能的水平值

輸出格式:

輸出最大戰鬥力值

樣例輸入:

3 5 10 1 5

1 3 1

樣例輸出:
12
約定:

1≤n≤100000,1≤a≤10^9,0≤cf,cm≤1000,0≤m≤10^15

題解:考慮貪心的策略,由於只有將乙個技能點到a或者提公升最低技能等級才能增加戰鬥力,所以說,只有兩種操作是有意義的

1.將乙個技能點到a

2.將所有最低等級的技能都點高一級,相當於提公升最低等級一級

所以我們可以從1-n列舉將i個技能點到a級所需要的最小花費,這個東西sort一下就能搞了,顯然點滿最大的前i個花費最小,然後用剩下的技能點高最低技能,其思路就相當於把剩下的水倒進低窪,去獲得此時水的高度一樣

這個高度顯然是可以二分的

用lower_bound搞出高度大於等於high的第乙個位置pos,然後顯然pos-1位置都是要填的,至於要填多少,顯然可以維護乙個字首和記錄已經填了多少了,再用high*(pos-1)-這個數就可以知道你要填多少,然後和你還剩的數比下哪個大就知道了,這東西是單調的,所以可以二分

不過要注意如果你已經把i個數點到a了,那麼pos的最大位置也就是n-i了

其次開局已經到a的技能還要特殊處理一下

**如下:

#include#include

#include

#include

#include

#define mod 1000000007

using

namespace

std;

long

long a[100010],n,aa,cf,cm,m,sum[100010

],tot;

int check(long

long high,long

long remain,int

now)

return0;

} intmain()

sort(a+1,a+n+1

);

while(a[n]==aa)

for(int i=1;i<=n;i++)

long

long cnt=0,ans=0

;

long

long l=1,r=1e9,mid,re=m-cnt;

while(l<=r)

else

if(r-l<=1

)

}ans=r*1ll*cm+tot*1ll*cf;

for(int i=1; i<=n; i++)

long

long l=1,r=1e9,mid,re=m-cnt;

while(l<=r)

else

if(r-l<=1

)

}ans=max(1ll*(i+tot)*cf+1ll*r*cm,ans);

}printf(

"%lld\n

",ans);

}

思路其實很簡單,但是真的是細節很多啊qaq

xjoi 二分查詢 道路規劃

70分 n 2 lis include include include include using namespace std int n,nor 100010 sou 100010 c 100010 q 100010 dp 100010 ans 0 int main for int i 1 i n...

新技能 二分答案

本來在刷圖論裡的題的,結果不小心遇到了這道luogu1462 想了好久也沒做出來,只有看題解了 怪我咯,略略略 好吧,這題要用二分 1.二分思想 其實和數學中的是一樣的,對於乙個單調函式,可以通過二分法來提高效率,從而更快的確定答案的範圍 或值 對於有單峰的函式,我們可以通過三分法來解決問題 2.二...

二分貪心 21

題目大概 有n堆積木,積木高度不同,每個小方塊高度相同。問,最少移動多少小方塊,使得這些積木堆高度相等。思路 先求這些積木的平均數,在把所有的高度與平均數的差值加起來,最後除2,就是最少移動的方塊數。感想 這個題有一點很坑人,最後輸出的時候有乙個小點,不注意看看不到。include include ...