P3694 邦邦的大合唱站隊 狀壓DP

2022-04-30 10:21:08 字數 1767 閱讀 7579

bang dream!裡的所有偶像樂隊要一起大合唱,不過在排隊上出了一些問題。

n個偶像排成一列,他們來自m個不同的樂隊。每個團隊至少有乙個偶像。

現在要求重新安排佇列,使來自同一樂隊的偶像連續的站在一起。重新安排的辦法是,讓若干偶像出列(剩下的偶像不動),然後讓出列的偶像乙個個歸隊到原來的空位,歸隊的位置任意。

請問最少讓多少偶像出列?

輸入格式:

第一行2個整數n,m。

接下來n個行,每行乙個整數 a_i(1\le a_i \le m)ai​(1≤ai​≤m) ,表示佇列中第i個偶像的團隊編號。

輸出格式:

乙個整數,表示答案

輸入樣例#1: 

12 413

2421

2311

34

輸出樣例#1: 

7

【樣例解釋】

1  3   √

3 3

2 3 √

4 4

2 4 √

1 2 √

2 2

3 2 √

1 1

1 1

3 1 √

4 1 √

【資料規模】

對於20%的資料, n\le 20, m=2n≤20,m=2

對於40%的資料, n\le 100, m\le 4n≤100,m≤4

對於70%的資料, n\le 2000, m\le 10n≤2000,m≤10

對於全部資料, 1\le n\le 10^5, m\le 201≤n≤105,m≤20

本蒟蒻做的第一道狀壓dp. 發現根本不會怎麼搞...結果竟然不僅看了題解定義的狀態,居然還看了轉移方程(我也是水到了一定境界).

看來 dp 還是不夠啊 ! !  

進入正題:

首先關於題意,有幾點需要注意:

1.每個人離開之後,會有乙個空位,而且肯定會有另外乙個人補上來.

2.最終狀態不一定要求團隊按正序排列.

狀態定義:

f [ i ] 表示當前達到這種狀態所需要請出去的最少的人.

然後關於 i 轉為 二進位制後上的每一位,都表示當前這個團隊已經站在了一起.

然後轉移方程:

j表示團隊編號,sum表示某種團隊的字首和.length表示到此已經排到的長度.

然後**裡面有解釋.

#includeusing

namespace

std;

intn,m;

int c[100008],f[1200000

];int sum[100008][25

];int

main()

}for(int i=0;i<(1

<)

f[i]=1341646

;

//賦值為極大值

f[0]=0

;

for(int i=0;i<(1

<)

}printf(

"%d\n

",f[(1

<1

]);

return0;

}

P3694 邦邦的大合唱站隊 狀壓dp

n nn個人,有m mm個隊伍,每個人都屬於乙個隊伍。要求叫出一些人來,然後任意插入出來的空隙中使得同一隊的人在一起。求最少出列人數。如果知道最終的佇列就可以十分容易的計算答案了。考慮乙個乙個隊伍的放入最終序列中,因為m mm十分的小,所以我們可以狀壓表示排好了的隊伍集合,然後用乙個字首和統計在乙個...

P3694 邦邦的大合唱站隊

bang dream 裡的所有偶像樂隊要一起大合唱,不過在排隊上出了一些問題。n個偶像排成一列,他們來自m個不同的樂隊。每個團隊至少有乙個偶像。現在要求重新安排佇列,使來自同一樂隊的偶像連續的站在一起。重新安排的辦法是,讓若干偶像出列 剩下的偶像不動 然後讓出列的偶像乙個個歸隊到原來的空位,歸隊的位...

P3694 邦邦的大合唱站隊 狀壓dp好題!!

題目 其實看這道題實際上就是列舉m個樂隊的排列,然後對應的站在該樂隊多佔的位置,卻不是該樂隊的人需要出隊。然後最後一定可站成同一團隊連續的排列。那麼下面的dp方程就很好理解啦。注意 從狀態s 在s後面放乙個樂隊j 一定需要增加的出隊的人數為 樂隊j所佔的容量num j 處不是樂隊j的人的個數。dp ...