輸入描述:
第一行三個數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條邊。...