NOI2019 序列(模擬費用流)

2022-06-20 14:09:14 字數 2356 閱讀 3250

有兩個長度為n的序列,要求從每個序列中選k個,並且滿足至少有l個位置都被選,問總和最大是多少。

\(1\leq l\leq k\leq n\leq 2*10^5\)。

首先,記錄當前考慮到的位置i,第乙個選的數量a, 第二個選的數量b,都被選的數量c,可以做到\(o(n^4)\),

卡常後能過\(n\leq 150\),有40分。

考慮正解:首先,看到這個範圍,可以認為正解一定是貪心。

先看下\(n\leq 2000\),這個是網路流的範圍。我們可以先建出費用流,然後再變為模擬費用流,即貪心。

從源點向第乙個序列連邊,第二個序列向匯點連邊。

然後,我們發現至少有l個位置都被選不太容易表示,因為左面向對應的右面連的邊是分開的,無法放到一起考慮下限。

換一種思路:至少有l個位置都被選,就是剩的位置不超過\(k-l\)。

所以,我們可以這樣建圖:

1、從源點向第乙個序列連邊,第二個序列向匯點連邊。

2、對應位置連流量為1的邊。

3、第乙個序列都向點a連邊,點b向第二個序列連邊。a到b連容量\(k-l\)的邊。

求出流量為k的最大費用流即可。這樣據說有64分。

考慮模擬費用流優化:

首先,記錄s表示a到b的剩餘流量。

1、若\(s>0\),則可以通過a到b的邊增廣,即從兩個序列中各選乙個最大數,並把s減去1。

2、可以直接走左右的對應連邊增廣,即選乙個左右相加最大的位置。

3、可以走\(s->x->x'->b->y'->t\),走\(x'->b\)的前提是x在第二個序列中被選。

即在第乙個序列中選乙個第二個序列中選的位置,再選乙個第二個序列中被選的作為y。

4、與3對稱,即在第二個序列中選乙個第乙個序列中選的位置,再選乙個第乙個序列中被選的。

因為是最長路增廣,所以在2,3,4中選最大的。以上操作可以用5個優先佇列完成。

然而,我們發現過不去樣例。

其實,演算法是對的,但我們少了一些情況(特判):

首先,還可以走\(s->x->x'->b->a->y->y'->t\)。(情況5)

就是在第二個序列中選乙個第乙個序列中選的位置,再在第乙個序列中選乙個第二個序列中選的位置,

因為退了a到b的流,要把s加1。

在1中,若選的兩個位置相同,則不用減s。若選的位置在另一串行中已被選,則為情況3或4,不用減s。

若選的位置在另一串行中已被選,則為情況5,把s加1。

在3,4中,可能會轉移到情況5,此時要把s加1。

加上這些後就能過了,實現時要注意細節。

#include #include using namespace std;

struct sjd

sjd(int z, int i)

};bool operator < (const sjd a, const sjd b)

#define prio priority_queue < sjd >

#define ll long long

int sa[200010],sb[200010],ba[200010],bb[200010];

prio pa,pb,pc,pd,pe,em;

inline int read()

int main()

int sy = k - l;

ll ans = 0;

for (int i = 0; i < k; i++)

while (!pb.empty())

if (sy > 0)

while (!pc.empty())

while (!pd.empty())

while (!pe.empty())

int ma = -1,

lx = -1;

if (!pc.empty() && !pb.empty() && rc.z + rb.z > ma) ma = rc.z + rb.z,lx = 1;

if (!pd.empty() && !pa.empty() && rd.z + ra.z > ma) ma = rd.z + ra.z,lx = 2;

if (!pe.empty() && re.z > ma) ma = re.z,lx = 3;

ans += ma;

if (lx == 1) else if (lx == 2) else if (lx == 3)

} printf("%lld\n", ans);

} return 0;

}

NOI2019 序列(模擬費用流)

有兩個長度為n的序列,要求從每個序列中選k個,並且滿足至少有l個位置都被選,問總和最大是多少。1 leq l leq k leq n leq 2 10 5 首先,記錄當前考慮到的位置i,第乙個選的數量a,第二個選的數量b,都被選的數量c,可以做到 o n 4 卡常後能過 n leq 150 有40分...

NOI2019 序列 貪心,模擬費用流

傳送門 首先你需要知道網路流的建圖方法,偷一張圖 我開始沒有想到怎麼限制 l 個相同,我們何不先選出 k 對,然後把 k 對拆開調整兩邊的最 擇 新建兩個點 c,d 來給兩邊調整的空間 我們可以模擬這個網路流的運作過程 類似某些貪心的題,用堆來維護最大之類的 我們可以記錄 cd 可以通過的流量 fl...

NOI2019 序列 題解

同步賽當場降智了,認為貪心是假的。然後。就寫了個暴力。開題一看,這不是模擬費用流嗎?然而這個費用流並不顯然。所以我當時放棄了t3部分分沒想到。當然也希望這個題解能讓大家懂得什麼是真正的模擬費用流啦 大概是這麼一張圖 正確性嘛 就是如果選下標不同的一對數的話必須走 c d 這條路徑 那麼就保證了下標不...