牛客網 每日一題 6月11日題目精講 揹包

2021-10-07 05:05:00 字數 1985 閱讀 3856

輸入描述:

第一行三個數v, n, m,分別代表揹包容量,物品數量以及需要取出的物品數量 接下來n行,每行兩個數ai,bi,分別代表物品價值以及大小 n

≤ 1e5, 1 ≤ m ≤ n, ai ≤ 1e9, v ≤ 1e9, bi ≤ v

輸出描述:

僅一行,代表最大的中位數

示例1

輸入

2053

3556

87106

1510

輸出

8
第一反應感覺是二分

m有奇數偶數兩種情況

當m是奇數時,左右分別取m/2個,最中間的就是我們要的答案

當m為偶數時,左邊取m/2-1個,右邊取m/2個,中位數為兩個數,就是當前第i個數和右邊第乙個數(因為我們列舉時只能選定乙個,所以就通過選定第i個把第i+1也確定)

接下來詳細講講過程

x[i]表示物品最小體積的字首和

y表示物品最小體積的字尾和

對於每乙個位置,我們列舉左右兩邊體積最小的m/2個數,(因為左右兩邊體積越小,給中間留的越多)

我們可以用優先佇列,從小到大依次放入,當揹包容量不夠時,去掉最大值,依次這樣操作,留到最後的就是合理值

當求奇數時,列舉每個位置,如果左右兩邊m/2個和中間的大小符合條件,則說明滿足條件。取最大的中間值

當求偶數時,最終答案是兩個數的平均值,我們列舉這兩個中左邊的數,左邊取m/2-1個右邊取m/2個。我們的序列是經過排序的,右邊的第乙個數取的越靠右

中位數就越大,但是越靠右他的物品總大小一定不會減少中位數就越大,但是越靠右他的物品總大小一定不會減少

可以發現,右邊選取物品的總大小是乙個遞增的可以發現,右邊選取物品的總大小是乙個遞增的

與此同時,他的價值也是遞增的,那麼可以發現與此同時,他的價值也是遞增的,那麼可以發現應該在大小符合的條件下盡量往右選,這就是明顯的二分啊應該在大小符合的條件下盡量往右選,這就是明顯的二分,直接二分右邊第乙個的位置找到盡量靠右的合法位置即可

題解借鑑

**是有問題的,但是我看了一陣子也沒找出來。。。

#include

const

int maxn=

1e5+2;

typedef

long

long ll;

using

namespace std;

struct nodew[maxn]

;ll x[maxn]

,y[maxn]

;//x表示前i個數(含第i個)取m/2個物品其大小的和的最小值

//y表示後i個數(含第i個)取m/2個物品其大小的和的最小值

bool

cmp1

(node a1,node b1)

priority_queue<

int>q;

long

long

int v,n,m;

//v n m

ll solve1()

}ll solve2()

if(r>i)sum=

max(sum,w[i]

.a+w[r]

.a);

//中間兩個值和的最大值

}return sum/2;

}int

main()

sort

(w+1

,w+1

+n,cmp1)

;int z=m&1;

m>>=1;

for(

int i=

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

while

(!q.

empty()

)q.pop()

;for

(int i=n;i;i--)}

if(z)

else

return0;

}

牛客網 每日一題 4月14日題目精講 Xorto

傳送時間限制 c c 2秒,其他語言4秒 空間限制 c c 32768k,其他語言65536k 64bit io format lld 給定乙個長度為n的整數陣列,問有多少對互不重疊的非空區間,使得兩個區間內的數的異或和為0。輸入描述 第一行乙個數n表示陣列長度 第二行n個整數表示陣列 1 n 10...

牛客網 每日一題 5月19日題目精講 比賽

時間限制 c c 1秒,其他語言2秒 空間限制 c c 131072k,其他語言262144k 64bit io format lld你在打比賽,這場比賽總共有12個題 對於第i個題,你的隊伍有a i 的機率解決她 如果解決不了她呢?由於所有人討論的都很大聲 所以你有b i 的概率從左邊那個隊那裡聽...

牛客網 每日一題 7月23日題目精講 wpy的請求

時間限制 c c 1秒,其他語言2秒 空間限制 c c 262144k,其他語言524288k special judge,64bit io format lld題目描述 題目名稱只是吸引你來做題的啦,其實和題目沒什麼卵關係 o o 歷史 殿堂 輸入描述 第一行兩個整數n,m,表示有n個點,m條邊。...