n
nn個物品,有兩個人,每個人有一些喜歡的物品。
選m
mm個物品,至少選擇k
kk個第乙個人喜歡的和k
kk個第二個人喜歡的物品
首先我們必定是選最小的
我們從小到大列舉選擇多少兩個人都喜歡的物品i
ii,然後每人選擇k−x
k-xk−
x只有這個人喜歡的物品,之後我們將剩下的物品丟進乙個資料結構裡,然後求前m−2
∗k+i
m-2*k+i
m−2∗k+
i個最小的物品。
現在我們需要維護乙個資料結構支援每次加入一些物品,然後求前z
zz個最小物品的和。我們發現z
zz是每次增加一的,可以使用對頂堆,保證第乙個堆內只有z
zz個物品然後每次如果更優就交換兩個堆堆頂的數
時間複雜度o(n
logn)
o(n\log n)
o(nlogn)
#include
#include
#include
#include
#define ll long long
using
namespace std;
const ll n=
2e5+10;
priority_queue q1,q2;
ll n,m,k;
ll ans,cnt,cnt1,cnt2,sum1,sum2,sum,sum0;
ll v[n]
,a[n]
,b[n]
,com[n]
,p1[n]
,p2[n]
;int
main()
scanf
("%lld"
,&num)
;for
(ll i=
1;i<=num;i++
)for
(ll i=
1;i<=n;i++
)sort
(com+
1,com+
1+cnt)
;sort
(p1+
1,p1+
1+cnt1)
;sort
(p2+
1,p2+
1+cnt2)
; ans=
1e18
;for
(ll i=
0;i<=
min(cnt,k)
;i++
)while
(cnt2>k-i)
ll ne=m-cnt1-cnt2-i;
if(ne<0)
continue;if
(cnt1+i!=k||cnt2+i!=k)
continue
;while
(!q1.
empty()
&&q2.
size()
while
(!q1.
empty()
&&!q2.
empty()
&&-q1.
top(
)top())
if(q2.
size()
>=ne)
ans=
min(ans,sum0+sum+sum1+sum2);}
if(ans==
1e18
)printf
("-1");
else
printf
("%lld"
,ans)
;}
14 7 新增職工
1 功能分析 用乙個陣列去儲存所有使用者新增的職工,但我們知道,陣列裡只能存放相同型別的元素。多型技術正好滿足的這一需求。例如,建立普通員工時可以這樣寫 worker worker new employee 建立經理時可以這樣寫 worker worker new manager 這樣,這個陣列裡儲...
nssl 1336 膜拜神牛
d es crip tion description descri ptio n 給定長度為n nn的序列a aa和b bb,若滿足ai aj a i geq a j ai aj 且bi b jb i leq b j bi bj 則i,ji,j i,j互相膜拜,求最大的互不膜拜集合 資料範圍 n 1...
nssl1476 聯 線段樹
無限長的01 0101 序列,每次進行乙個操作 區間內賦值為0 00區間內賦值為1 11區間取反 求第乙個0 00的位置 離散化 儲存每個區間的左右端點和他們加一之後的值 後可以用線段樹儲存第乙個0 00和第乙個1 11的位置。然後區間取反時就交換兩個值並且讓laz ylazy lazy 標記同樣取...