hdu6321 狀態壓縮

2021-08-21 23:32:48 字數 1319 閱讀 7493

昨天打的多校賽,打到一半去打cf了,然後今天看見題解發現第三題是如此簡單易懂。

題目鏈結戳下面

hdu6321

題目大意為給你n個點(

n<=10,

n n

<=10,

n)

初始時沒有邊相連

然後有m個操作(

m<=

30000

m

<=

30000

) 每次可以新增一條邊或刪除一條邊

允許有重邊

要求每次操作過後輸出選這個圖中不相交的k條邊有多少種不同的方案 (k

=1,2

,3……

n/2)

( k=

1,2,

3……n

/2

)以下是解題思路:

設s是點集,表示選擇的邊由這個點集裡的點組成,由於邊不相交,易知

邊數=點數/2

f(s)表示這個點集選不相交的邊的方案數

當一條邊(u,v)被加入時,若s包含(u,v),則

f(s)=f(s)+f(s-u-v);

當一條邊(u,v)被刪除時,若s包含(u,v),則

f(s)=f(s)-f(s-u-v);

因為這個f(s)其實是降了維的,類似揹包降維需要從後往前更新一樣,在加邊時s需要從大到小更新,而刪除時則相反。

我們怎麼表示s呢?

我們將n個點的狀態壓縮成數字,某一位為1表示選擇該點,0表示不選。

以下為ac**

#include 

#define mod 1000000007

#define mod(x) ((x)%mod)

using

namespace

std;

const

int maxn = 30005;

int cnt[1050];

int f[1050];

int ans[10];

bool judge(int s,int x,int y)

int main()

scanf("%d",&t);

while(t--)}}

else}}

int ll=n/2;

for(int i=1;i<=ll;i++)

for(int i=1;iif(cnt[i]%2==0)

ans[cnt[i]/2]=mod(ans[cnt[i]/2]+f[i]);

}for(int i=1;i<=ll;i++)}}

return

0;}

hdu1074狀態壓縮

很明顯的狀態壓縮題目。當然了如果他的意識只有是求最小值沒有要求輸出那個輸出的順序,那麼直接用揹包,甚至是貪心都是可以做出來的,但是要求順序這個揹包的話沒有辦法吧資料記錄下來。所以用二進位制壓縮。所謂的二進位制壓縮就是用二進位制來表示事情的完成程度和狀況,比如1,就是0000001表示第乙個作業做了,...

1074 HDU 狀態壓縮

首先貼兩個狀態壓縮的題解,這是第乙個狀態壓縮dp,想了一下午,不知道是不是有點慢 然後在貼下我自己的 include include include include include include include include define ll int64 define max 1000009 ...

Hdu 1429(狀態壓縮)

有鑰匙和門的 bfs 狀態壓縮 乙個十把鑰匙和鎖,分別為a,b.j 當所用的步數小於 t即可。include include include includeusing namespace std int n,m,t,ans char map 21 21 int dir 4 2 int vis 21 ...