有n
nn個卡包,第i
ii個卡包裡有c
ic_i
ci張卡,每張卡有乙個能力值。現在從每個卡包裡面選一張卡,定義一種方案的價值為選的卡的能力值之和,求價值前k
kk大的方案。
n ,k
,∑ci
≤300000
n,k,\sum c_i\le300000
n,k,∑c
i≤3
0000
0 很自然的想法是用乙個堆來維護所有狀態的價值,從價值最大的狀態開始,每次往後拓展一些狀態,關鍵在於如何設定狀態。
先把所有卡組的卡按能力值從大到小排序。設(va
l,x,
y,z)
(val,x,y,z)
(val,x
,y,z
)為乙個狀態,其中val
valva
l表示狀態的價值,處理了前x
xx個卡組,第x
xx個卡組選的是第y
yy張卡,z表示當前狀態是否由2或3操作轉移而來,且編號大於x
xx的卡組選的均為第一張卡。
然後有如下轉移:
1、若y
yy,也就是第x xx個卡組還能繼續拓展,則轉移到(va l+.. .,x, y+1, 0) (val+...,x,y+1,0) (val+. ..,x ,y+1 ,0)2、若y y< n,也就是還能拓展到下乙個卡包,則讓下乙個卡包選擇第二章卡,也就是轉移到(va l+.. .,x+ 1,2, 1) (val+...,x+1,2,1) (val+. ..,x +1,2 ,1)3、若x x=1 z=1z= 1,也就是當前卡組選的是第二張卡,且還能拓展到下乙個卡包,則撤銷掉當前卡組的第二張卡,並選擇下乙個卡組的第二張卡,也就是轉移到(va l+.. .,x+ 1,2, 1) (val+...,x+1,2,1) (val+. ..,x +1,2 ,1)可以發現這樣可以不重不漏地構造出所有方案,而如果我們把卡組按照最大值 −次大值 最大值-次大值 最大值−次大 值從小到大排序,就可以保證每次被轉移到狀態的價值必然會小於當前狀態的價值,那麼就可以按照價值從大到小地列舉方案了。 #include #include #include #include #include #include #define pb push_back typedef long long ll; const int n= 300005 ;int k,n,id[n] ;std: :vector< int> vec[n] ;struct data}; std: :priority_queue que; bool cmp (int x, int y) bool cmp (int x, int y) intmain() } n=tmp; for( int i= 1;i<=n;i++ ) id[i] =i; std: :sort (id+ 1,id+n+ 1,cmp) ;for (int i= 1;i<=n;i++ ) sum+ =vec[i][0 ];que. push ((data)); while (k--)) ;if(xpush ((data)); if(x1) que. push ((data)); }return0; } 題目描述 a 是某公司的 ceo,每個月都會有員工把公司的盈利資料送給 a,a 是個與眾不同的怪人,a 不注重盈利還是虧本,而是喜歡研究 完美序列 一段連續的序列滿足序列中的數互不相同。a 想知道區間 l,r l,r 之間最長的完美序列長度。輸入格式 第一行兩個整數 n,m n,m,n n 表示連續... 題目鏈結 給定 n 求 f n sum n sum i frac i,j bmod 10 9 7 1 le n le 10 9 首先,這個求和範圍有些不爽,利用對稱性轉化一下得 f n frac 12 left n sum n sum n frac i,j right 然後推一下式子 begin s... 某一天,你發現了乙個神奇的函式f x f x 它滿足很多神奇的性質 1.f 1 1 f 1 12.f pc p c f p c p c 表示異或 3.f a b f a f b f a b f a f b a a 與b role presentation b b互質 你看到這個函式之後十分高興,於是...#include
與眾不同 LibreOJ 10121
題解 LibreOJ 6229 題解
LibreOJ 6053 簡單的函式