插頭DP學習

2022-08-19 15:03:10 字數 3521 閱讀 7560

隊內沒人會插頭dp,感覺這個不會不行。。。所以我還是默默去學了一下,

學了一天,感覺會了一點。對於每一行,一共有j+1個插頭,如果是多迴路類的題目,

比較簡單,可以用1表示有插頭,0表示沒有插頭,這樣就可以愉快轉移了,

對於當前出來的位置(i,j),與它有關的插頭有j-1和j 那麼我們可以列舉狀態經行轉移。

對於單迴路的問題。。。。只是了解思想,目前還不會寫,太笨了=_=

poj 2411 mondriaan's dream

題意:用1*2小方塊組成n*m矩陣有多少種組成方式

思路:我們從上到下處理每一行,對於當前處理的位置 (i,j),列舉它的插頭狀態,0~(1<

假設狀態是 sta,如果sta表示的狀態沒有j-1和j 插頭(即(sta&(1<

如果sta表示的狀態都有j-1和j 插頭,這樣狀態是不合法的,直接=0

如果sta表示的狀態j 插頭,表示是平放方塊,這個狀態只能由j-1,j插頭不存在狀態轉移過來

如果sta表示的狀態j-1 插頭,表示是豎放方塊,這個狀態只能由j-1,j插頭不存在狀態轉移過來

#include#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define inf 999999

#define maxn 200001

#define mod 1000000007

#define inf 0x3f3f3f3f

using

namespace

std;

int mat[15][15

];ll dp[

12][12][(1

<<13)+10

] ;int

main()

memset(dp,

0,sizeof

(dp)) ;

len=(1

<

)); dp[

0][m][0]=1

;

for( i = 1 ; i <= n ;i++)

else

if((sta&x)==0&&0==(sta&y))

else

if((sta&x))

dp[i][k][sta]=dp[i][k-1][sta^x];

else dp[i][k][sta]=dp[i][k-1][sta^y];}}

}printf(

"%i64d\n

",dp[n][m][0

]); }

return0;

}

view code

hdu 4804 campus design

題意:和上題差不多,多了的東西是,有些地方不能放方塊,

還有可以放1*1方塊,求的是 1*1放的個數限制在c-d內的放的方式有多少種

思路:具體做法和上面也是差不多,

差別:對於1*1放置個數的限制,我們可以開多一維記錄1*1用的個數,

對於不能放置的位置(i,j ),合法的狀態sta,裡面不能有 j-1,j 插頭

對於可以放置的位置(1,j) ,狀態是 sta,如果sta表示的狀態沒有j-1和j 插頭時

多了一步轉移,就是 放置1*1的狀態。

#include#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define inf 999999

#define maxn 200001

#define mod 1000000007

#define inf 0x3f3f3f3f

using

namespace

std;

char mat[105][25

];int dp[2][12][22][(1

<<12)+10

];int

main()

else dp[now][k][v][sta]=dp[now][k-1

][v][sta] ;

}else

else

if((sta&x) == 0 &&(sta&y) == 0

)

else

if((sta&x))

dp[now][k][v][sta]=dp[now][k-1][v][sta^x];

else dp[now][k][v][sta]=dp[now][k-1][v][sta^y];}}

}}

int ans1=0

;

for( i = c ; i <= d;i++)

ans1=(ans1+dp[now][m][i][0])%mod;

printf(

"%d\n

",ans1);

}return0;

}

view code

hdu 1693eat the trees

題意:在n*m的矩陣中,有些格仔有樹,沒有樹的格仔不能到達,找一條或多條迴路,吃完所有的樹,求有多少中方法。

思路:看這個部落格吧,here

#include#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define inf 999999

#define maxn 200001

#define mod 1000000007

#define inf 0x3f3f3f3f

using

namespace

std;

int mat[15][15

];ll dp[

12][12][(1

<<13)+10

] ;int

main()

else}}

}printf(

"case %d:

",++case1);

printf(

"there are %i64d ways to eat the trees.\n

",dp[n][m][0

]); }

return0;

}

view code

學習筆記 插頭DP

基於連通性的狀壓dp問題。一般是給你乙個網格,有一些連通性的限制。鏈結題意 網格圖,去掉一些點,求哈密頓迴路方案數。一般按格遞推 從上到下,從左到右 每個格仔要從四個方向中選兩個作出邊。我們只需要記錄紅色的輪廓線的狀態,是否有邊伸出這個線 稱之為插頭 還要記錄伸出來的邊的連通性。記錄連通性的方法 最...

插頭dp學習筆記

由於插頭dp很難懂於是又來記筆記了 插頭dp可以用來解決一些連通性狀壓問題。具體流程是分格仔處理,然後可以根據需要進行滾動,狀壓一下輪廓線狀態,常用4進製 之類的。拿luogu例題做例子 給出n m的方格,有些格仔不能鋪線,其它格仔必須鋪,形成乙個閉合迴路。問有多少種鋪法?n,m 2 n,m 12 ...

插頭DP 入門

強烈推薦 hdu 1693 eat the trees 多迴路的不用判聯通狀態,二進位制即可,轉移情況2 2種。時間o n m 2 n 空間o n 2 n 插頭dp include include const int maxm 13 const int maxn 1 12 typedef long ...