早上寫了一篇,就還想再寫一篇
挺不錯的乙個題
先來講講部分分吧
第一檔13分的很簡單,直接爆搜就可以了
第二檔11分的也很簡單,直接排個序就可以了
然後有一檔6分的,m=2
,b
=m=2,b=\
m=2,b=
,這的話,稍作思考,可以發現,每一次一定是選兩個最小的數合起來
然後剩下的檔我就不會了。。
算了一下只可以拿到13+11
+6=30
13+11+6=30
13+11+
6=30
蠻低的暴力分吧
其實如果你會第三檔,24
2424
分的,基本上離正解也不遠了
先說24
2424
分的吧正解要想到二分答案,然後倒過來做
那麼問題就變成了,你一開始有乙個數x
xx,然後每一次,你可以把你的數集裡面的某乙個數a
aa,把他拆成m
mm個數,並且要求拆出來的m個數,都要滿足都比a
ia_i
ai要大。正確性其實挺顯然的。
然後你考慮,滿分的話
問題就等價於,你拆成n個數以後,可以找到乙個對應方案,使得每乙個數都比對應的a
ia_i
ai大
這個做法其實也不錯的
我們可以進行討論
我們把當前數集的值x
xx拿出來,然後看一下目標數集的最大值y
yy,再看一下b
bb的最小值b′b'
b′如果x −b
′<
yx-b'x−
b′<
y,那麼顯然,y是不可能由別的東西拆開得到了,因此,找乙個剛好比他大的數,對應起來即可
否則就把x拆開,這個,其實正確性也挺顯然的,因為你拆別的不會比拆這個要優
當你得到了n個數的時候,check一下就可以了
時間複雜度顯然是對的
code:
#include
#include
#include
#include
#include
using
namespace std;
const
int n=
50005
;int n,m;
int a[n]
,b[n]
;multiset<
int> s;
multiset<
int>
:: iterator it;
bool check (
int x)
//這個答案行不行
else
}int i=1;
for(it=s.
begin()
;it!=s.
end(
)&&i<=now;it++
,i++)if
(a[i]
>
(*it)
)return
false
;return
true;}
intmain()
else l=mid+1;
}printf
("%d\n"
,ans)
;return0;
}
UOJ 177 新年的腮雷
你有乙個長度為n的序列a,和乙個長度為m的序列b 你每次可以選擇m個a中的數x1 xm合併 順序任意 合併會剩下乙個數,為min xi bi 你需要讓剩下的最後的數最小。n 50000 正著做似乎怎麼都有問題,考慮倒過來 二分答案,我們每次考慮把乙個數x拆分成m個數x b i 這樣一定限制最松 我們...
uoj 176 新年的繁榮
給出乙個完全圖,邊權為兩點權值的and,求最大生成樹。這題用最小生成樹的boruvka演算法。大概就是每次找到每乙個聯通塊權值最大的邊,將這些聯通塊合併,直到只剩乙個聯通塊。因為每次聯通塊的個數至少減半,所以只會做log次操作。那麼這題相當於每個點有不同顏色,要找到每個點的異色點中最大的and值。扔...
uoj 175 新年的網警
在這新年的第一天,猴族首領猴腮雷打算來整治一下網路風氣。這時,他聽說在乙個叫做 universal oj 使用者群 的 qq 群中有人在散播 開 謠言 車 於是他就派了一群網警把這個使用者群裡的人都抓了回來,試圖找到謠言的源頭。這個使用者群中有 nn 個人,這些人中存在 mm 對雙向的直接認識關係,...