Foreign 減法 二分 貪心

2022-05-20 06:53:24 字數 1893 閱讀 6336

time limit: 10 sec  memory limit: 256 mb

給你乙個n個數的序列a,並且給出m次操作b。

操作的含義是:每次從a中選出不同的b_i個數,把它們減去1。乙個數》0被看作是可以選擇的。

問最多執行完第幾個操作。

第一行給出兩個整數,序列長度n與運算元m。

第二行n個數,表示序列a。

第三行m個數,表示操作序列b。

輸出乙個整數,表示最多執行完第幾個操作。

3 42 1 3

3 1 2 1

1 <= n, m <=100000

考慮貪心,顯然是每次減去大的數

我們二分答案做到第幾次,然後構造一組不上公升序列times,表示每個數最多可以被減幾次,每次把區間[1, b[i]]加一。

如果每個數都足夠大的話,這顯然是一組合法解。但是每個數不一定都夠減

我們可以基於這個序列來做調整,考慮什麼情況下是合法的呢?

顯然,前面不夠減的可以是分攤到後面去,而若a從大到小排序,貪心盡量多減,那麼後面減的次數不可能比前面多,所以這樣就保證了合法性

所以先把a從大到小排序然後o(n)遞推。

每次left += times[i] - a[i]

如果left<=0,表示這個位置的值減完還有剩餘,但是這個left不能分攤給後面用,所以我們把left設為0

如果left>0,可以把left留在後面減,傳遞下去即可。

遞推完只要判斷一下最後是否left<=0

1 #include2 #include

3 #include4 #include5 #include6 #include7 #include8

using

namespace

std;

9 typedef long

long

s64;

1011

const

int one = 1000005;12

const

int mod = 1e9 + 7;13

14int

n, m;

15int

a[one], b[one];

16int

times[one];

17bool cmp(int a, int b)

1819

intget

()20

2930

int check(int

mid)

3138

39int left = 0;40

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

4146

47return left <= 0;48

}4950int

main()

5164

65if(check(r)) printf("%d"

, r);

66else printf("%d"

, l);

67 }

view code

二分貪心 21

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

二分貪心 E

題目 輸入n和c,n代表有n間屋子c代表有c頭牛,然後輸入n個數代表這n間房子的座標,牛不喜歡這個布局,一進去就會很暴躁,所以要把牛分的盡可能的遠求最近兩頭牛的最大距離。解題思路 建立乙個陣列存這些房子的座標,然後用sort將這些座標排序,然後令l 0,r a n mid l r 2,先用mid當作...

二分貪心 T

題目 有1 1,2 2,3 3,4 4,5 5,6 6大小的盒子,要把它們裝到6 6的盒子裡,它們的高度都是相同的,用最少的6 6盒子把所有尺寸的盒子都裝起來。解題思路 6 6,5 5以及4 4尺寸的物品每個物品需要占有乙個箱子,3 3的物品乙個箱子可以放4個,2 2的物品箱子可以放9個,1 1的可...