學習狀壓之前必須要熟練掌握位運算
位運算名
符號效果
&(and)
按位與如果兩個相應的二進位制位都為1,則該位的結果值為1,否則為0
l(or)
按位或兩個相應的二進位制位中只要有乙個為1,該位的結果值為1
^(xor)
按位異或(單身狗操作)
若參加運算的兩個二進位制位值相同則為0,否則為1~取反
一元運算子,用來對乙個二進位制數按位取\反,即將0變1,將1變0
<<
左移用來將乙個數的各二進位制位全部左移n位,右補0
>>
右移將乙個數的各二進位制位右移n位,移到右端 的低位被捨棄,對於無符號數,高位補0
下面是一些基本操作
動態規劃必須滿足無後效性原則,即則此階段以後過程的發展變化僅與此階段的狀態有關,而與過程在此階段以前的階段所經歷過的狀態無關。通俗來講也就是說i的狀態只能由i-1來決定
題目描述
農場主john新買了一塊長方形的新牧場,這塊牧場被劃分成m行n列(1 ≤ m ≤ 12; 1 ≤ n ≤ 12),每一格都是一塊正方形的土地。john打算在牧場上的某幾格里種上美味的草,供他的奶牛們享用。
遺憾的是,有些土地相當貧瘠,不能用來種草。並且,奶牛們喜歡獨佔一塊草地的感覺,於是john不會選擇兩塊相鄰的土地,也就是說,沒有哪兩塊草地有公共邊。
john想知道,如果不考慮草地的總塊數,那麼,一共有多少種種植方案可供他選擇?(當然,把新牧場完全荒廢也是一種方案)
輸入輸出格式
輸入格式:
第一行:兩個整數m和n,用空格隔開。
第2到第m+1行:每行包含n個用空格隔開的整數,描述了每塊土地的狀態。第i+1行描述了第i行的土地,所有整數均為0或1,是1的話,表示這塊土地足夠肥沃,0則表示這塊土地不適合種草。
輸出格式:
乙個整數,即牧場分配總方案數除以100,000,000的餘數
輸入輸出樣例
輸入樣例#1:
2 3
1 1 1
0 1 0
輸出樣例#1:
9
**#include
#define mod 100000000
using
namespace std;
const
int m=
15,n=
1<<15;
int st[n]
,mp[m]
//存可行的不相鄰的狀態以及圖中每排的狀態;
int dp[m]
[n];
//存每排
int n,m;
int ans;
inline
intread()
while
(ch<=
'9'&&ch>=
'0')
return x*f;
}bool
judge1
(int x)
//判斷相鄰兩點是否衝突
bool
judge2
(int i,
int x)
//判斷點能不能放
intmain()
}int k=0;
for(
int i=
0;i<
;i++
)for
(int i=
1;i<=k;i++
)for
(int i=
2;i<=n;i++)}
}for
(int i=
1;i<=k;i++
)printf
("%d"
,ans)
;return0;
}
題目描述在n×n的棋盤裡面放k個國王,使他們互不攻擊,共有多少種擺放方案。國王能攻擊到它上下左右,以及左上左下右上右下八個方向上附近的各乙個格仔,共8個格仔。
輸入輸出格式
輸入格式:
只有一行,包含兩個數n,k ( 1 <=n <=9, 0 <= k <= n * n)
輸出格式:
所得的方案數
輸入輸出樣例
輸入樣例#1:
3 2
輸出樣例#1:
16
**
#include
using
namespace std;
const
int n=
10,m=
1<<10;
int st[m]
;//表示所有狀態
long
long f[n]
[m][n*n]
;//表示第i行,狀態為j,前面擺了k個國王時,方案數;
int king[m]
;//表示每個狀態所對應的國王數
int n,k;
inline
intread()
while
(ch>=
'0'&&ch<=
'9')
return x*f;
}bool
judge
(int x)
//兩個國王之間必須隔乙個,判斷是否滿足題意國王之間不相互攻擊;
intmain()
//判斷這個狀態有多少個國王,也就是t在二進位制下有多少個1;}}
//找出所有合法的狀態以及該狀態國王的數量
for(
int i=
1;i<=t;i++)if
(king[i]
<=k)
f[1][i]
[king[i]]=
1;//先處理第一行;
for(
int i=
2;i<=n;i++
)//處理剩下的,所以從 2 開始列舉;
for(
int j=
1;j<=t;j++
)//列舉當前行狀態;
for(
int l=
1;l<=t;l++
)//再一遍狀態,用來當作上一行的狀態,因為有效狀態轉移是從上一行開始的;
}long
long ans=0;
for(
int i=
1;i<=n;i++
)//不確定在哪一行用光國王,所以都列舉一遍;
for(
int j=
1;j<=t;j++
) ans+
=f[i]
[j][k]
;//本行及以前用光了國王,那麼方案數加在總數中;
printf
("%lld"
,ans)
;return0;
}`
狀壓DP入門題集錦
poj 3254corn fields 題意 一塊n m的田,1表示這個地方可以種植,0代表這個地方不能種植。植物種植還必須滿足兩株植物不能相鄰 橫豎都不行 問共有幾種種植方法,而且當什麼都不種時認為是一種方法。解題思路 種植用1表示,不種植用0表示。每一行的情況就可以用乙個二進位制數state來儲...
狀壓DP入門
洛谷題號p1896 在n n的棋盤裡面放k個國王,使他們互不攻擊,共有多少種擺放方案。國王能攻擊到它上下左右,以及左上左下右上右下八個方向上附近的各乙個格仔,共8個格仔。題解 首先暴搜可肯定是超時的所以我門考慮狀壓 因為每個數都可以用二進位制表示出來 二進位制中01可以表示當前行放的棋子的位置 以及...
狀壓DP入門
首發於摸魚世界 狀壓dp,即狀態壓縮dp,它的精髓在於把dp過程中的乙個 狀態 用乙個二進位制數巧妙的表示出來。接下來就從一些入門的狀壓題目來感受一下狀壓的魅力吧 洛谷p5911 poi2004 prz 大致題意 n 個人過最大承載 w 重量的橋,每個人有重量 w i 與過橋時間 t i 多人一組時...