題意:給定數n(n<=17),求乙個n位數,每位可選1…n中的乙個,且每位不同,並且滿足給定的條件,求方案數。給定條件為m個:x y 表示第x位為y的滿足要求。
滿足m中的乙個條件即正確。
演算法:dp 狀態壓縮
分析:首先不考慮條件的總方案數為n!
我們先算不滿足條件的方案,因為m個條件之間是或者 關係,有重疊。算取反面較為簡單。即將題意抽象成:
有n個排列有序的集合,每個集合中原有元素1…n,但是有一些元素不能取(即為m個條件限制),求從每個集合選出乙個元素,且所有選出元素不重複的方案數。
因為n<=17 搜尋顯然是要超時的,這個時候我們考慮到只有17個數字,2^17=131072。
每個數字只有兩種狀態,取或者不取,所以可以用二進位制來表示當前的狀態。
有狀態轉移方程: f[i][j]-> f[i+1][now] | 滿足第i+1個集合可以取數 k,並且狀態j中沒有取數k,即 j&(1<<(k-1))==0. now表示加上k的狀態.
再注意到資料的範圍需要long long
並且最後輸出若用%lld 便wa ,%i64d便ac
#include#include#include#include#define rep(i,n) for(int i=0;i
hdu 1074 狀態壓縮dp
題目描述 有 n 門課程的作業,每門都有完成期限d,與完成所需時間c,若超過期限,1天扣1分。問完成這n門作業至少要扣多少分,並輸出扣分最少的做作業順序。思路 dp i 記錄完成狀態為i的情況下的資訊。完成所需時間,上乙個狀態,最小扣分 狀態方程 dp i min dp j cost j,i 從j狀...
hdu1565 dp狀態壓縮
題意 給你乙個n n的格仔的棋盤,每個格仔裡面有乙個非負數。從中取出若干個數,使得任意的兩個數所在的格仔沒有公共邊,就是說所取的數所在的2個格仔不能相鄰,並且取出的數的和最大。解題思路 先找出所有能成立的狀態,即 i i 1 0,表示每一行都沒有相鄰的,然後遍歷if q j 1 再進行動態更新,用上...
hdu 3001(狀態壓縮dp)
include include include define max1 10 define max2 59049 3 10 define inf 0x3f3f3f3f using namespace std 由於每個點可經過兩次 用三進製數表示狀態 例10020 三進製 表示經過點2兩次點1一次其餘...