1
:判斷二進位製上某一位是不是1:
if( x>>i&1==
1)右移i位和1相與
2:將二進位制第i位改為1:
x = x |(1
<:將二進位制第i位反**
x = x ^(1
<:把二進位制從右數第乙個「1」捨棄:
x = x &
(x-1);
5:在二進位制下,判斷a與b,若b的位數中是1時,不允許a的位數中有0
a & b != b
6:列舉x的子集:即列舉的數j的位數中,x是0的,j也一定要是0
for(
int j = x; j >
0; j =
(j-1
)&x )
題意:從 0 走到 n-1號點,途中以任意順序經過其它所有點,求最短的路徑。(給出邊權)
資料範圍: 1<=n<=20
暴力:o(n
!)==
10
18o( n! ) == 10^
o(n!)=
=101
8 狀壓dp: o(2
n∗n2
)==1
08
o( 2^n *n^2 ) == 10^
o(2n∗n
2)==
108
ac **:
#
include
using namespace std;
int n;
int dp[
1<<20]
[21];
int weight[21]
[21];
intmain()
}memset
(dp,
0x3f
,sizeof
(dp));
dp[0001][
0]=0
;//集合中只包含第0個點,當前駐足在 0 點
// 遍歷 00000001 ~ 11111111 點的集合
for(
int state =
1; state <(1
<; state ++)}
}}}// 二進位制下:dp[111111111][n-1] :所有點都在集合中,並且當前在 n-1位置上
cout<<][n-1]
<}
題意:給定n個點m條邊的無向圖,
要求刪掉若干邊,使得圖為若干個連通塊,滿足每個連通塊都是完全圖,
問最少的連通塊數量是多少。
資料範圍:1
<=n
<=18
1<=n<=18
1<=n
<=1
8 狀壓dp :dp[
maxn
]:ma
xn=1
<
<
18dp[maxn]: maxn = 1<<18
dp[max
n]:m
axn=
1<
<18
(2的18次方)
dp[i] : 當點集為i時,(如i=5,二進位制位101,點集為 0,2號點),滿足題面的最小連通塊數目
轉移方程 :dp[
stat
e]=m
in(d
p[st
ate]
,dp[
stat
e−j]
+dp[
j]);
dp[state] = min( dp[state] , dp[state - j] + dp[ j ] ) ;
dp[sta
te]=
min(
dp[s
tate
],dp
[sta
te−j
]+dp
[j])
; ac**:
#
include
using namespace std;
int dp[
1<<18]
;int n,m;
int edge[20]
;void
init()
intmain()
memset
(dp,
0x3f
,sizeof
(dp));
dp[0]
=0;for
(int state =
1; state <(1
<; state++)}
//完全圖,則強連通分量為 1
if(complete) dp[state]=1
;//列舉當前集合的所有子集
//state二進位制位上為 0的,j該位必須為 0
for(
int j=state; j>
0; j=
(j-1
)&state)}
cout<<]<}
狀壓dp 玉公尺田 狀壓dp
相關 強相關 327.玉公尺田 狀壓dp 小國王 狀壓dp 是井字形,本題是十字形。思路 狀態計算 時間複雜度 n 2 n 2n o n 22n 12 2 24n 2 n 2 n o n2 12 2 n 2n 2 n o n22n 12 224 看著妥妥超時,但是裡面合法狀態很少 依舊可以過 在此,...
狀壓dp小記
鋪磚 題意 現有nm的一塊地板,需要用12的磚塊去鋪滿,中間不能留有空隙。問這樣方案有多少種 include using namespace std typedef long long ll const int maxn 1 11 int n,m,state ll dp 15 maxn s1表示本行...
狀壓dp學習
p2704 炮兵陣地 1038 裁玻璃 狀壓dp是一種非常暴力的做法,列舉所有可能的狀態,找到要求的最佳狀態,與一般dp不同,前一項與後一項有一些複雜的狀態關係。dp的引數 物品個數 行數等 當前狀態 上乙個狀態 將abc的有無表示成乙個8個狀態,列舉所有組,列舉上乙個狀態,得到當前狀態的最優解 i...