隊內沒人會插頭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#includeview code#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;
}
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#includeview code#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;
}
hdu 1693eat the trees
題意:在n*m的矩陣中,有些格仔有樹,沒有樹的格仔不能到達,找一條或多條迴路,吃完所有的樹,求有多少中方法。
思路:看這個部落格吧,here
#include#includeview code#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;
}
學習筆記 插頭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 ...