P3694-邦邦的大合唱站队【状压dp】
生活随笔
收集整理的這篇文章主要介紹了
P3694-邦邦的大合唱站队【状压dp】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目鏈接:https://www.luogu.com.cn/problem/P3694
題目大意
nnn個人,有mmm個隊伍,每個人都屬于一個隊伍。要求叫出一些人來,然后任意插入出來的空隙中使得同一隊的人在一起。求最少出列人數。
解題思路
如果知道最終的隊列就可以十分容易的計算答案了。考慮一個一個隊伍的放入最終序列中,因為mmm十分的小,所以我們可以狀壓表示排好了的隊伍集合,然后用一個前綴和統計在一個區域內每個隊伍的人數即可進行dpdpdp。
時間復雜度O(nm+2mm)O(nm+2^mm)O(nm+2mm)
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,m,s[110000][20],wz[1<<20],f[1<<20]; int main() {scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){int x;scanf("%d",&x);x--;for(int j=0;j<m;j++)s[i][j]=s[i-1][j]+(x==j);}int MS=1<<m;for(int i=0;i<MS;i++)for(int j=0;j<m;j++)wz[i]+=s[n][j]*((i>>j)&1);memset(f,0x3f,sizeof(f));f[0]=0;for(int i=1;i<MS;i++){for(int j=0;j<m;j++){int k=i^(1<<j);if(k>i)continue;f[i]=min(f[i],f[k]+s[n][j]-s[wz[i]][j]+s[wz[k]][j]);}}printf("%d",f[MS-1]); }總結
以上是生活随笔為你收集整理的P3694-邦邦的大合唱站队【状压dp】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mac上如何显示快捷键Mac上的快捷键
- 下一篇: 怎样可以更改有线路线路由器的秘密家中路由