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

2022-01-10 18:16:27 字數 1208 閱讀 5977

首先要注意合唱隊排好隊之後不一定是按\(1.2.3......m\)的順序的

\(n\)的範圍很大,但\(m\)的資料比較小,所以我們考慮裝壓dp

我們設\(f[i]\)為狀態為\(i\)的合唱隊已經安排好位置的最小花費

接下來就是狀態轉移方程的問題

for(int i=1;i

我們用乙個變數\(len\)記錄排好隊的總人數,如果當前合唱隊已經排好了隊,那麼我們把總人數加上當前合唱隊的人數

其中,編號為\(j\)的合唱隊的總人數\(num[j]\)可以預處理

為什麼這樣做呢?

因為我們無論讓偶像們怎麼出隊,他們最終的狀態是確定的,肯定是乙個合唱隊的偶像站到一起,因此我們就可以統計排好隊後當前區間的總長度

接下來就是狀態轉移

如果編號為\(j\)的合唱隊在我們決策的範圍之內,那我們就需要嘗試將編號為\(j\)的合唱隊的全體成員都放在隊伍最後

那麼此時我們就需要將編號為\(j\)的合唱隊中不在區間\([len-num[j]+1,num[j]]\)的偶像移到該區間

此時的花費為\(num[j]-sum[len][j]+sum[len-num[j]][j]\)

其中\(sum[i][j]\)表示開始時前\(i\)個位置中編號為\(j\)的合唱隊員的個數

問題就可以解決了

#includeusing namespace std;

const int maxn=22,maxm=1e5+5;

int f[1<

int num[maxn],sum[maxm][maxn];

int main()

memset(f,0x3f,sizeof(f));

f[0]=0;

for(int i=1;i

for(int j=1;j<=m;j++)

}printf("%d\n",f[(1<< m)-1]);

return 0;

}

洛谷 P3694 邦邦的大合唱站隊

題目鏈結 m 很小,考慮狀壓。狀態 s 一共有 m 位,每一位代表當前樂隊是否排好 即樂隊所有成員都站在一起 並假設所有排好的樂隊都站在前面。f s 表示狀態為 s 時最少移動的偶像數目。不管所有排好的樂隊順序如何,它們的總數是一定的。列舉 s 狀態中的每乙個 0 如果將它變成 1 並接在所有排好的...

P3694 邦邦的大合唱站隊

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

洛谷P3694 邦邦的大合唱站隊 簽到題

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