狀態壓縮動態規劃(簡稱狀壓dp)是非常典型的一類dp。他是利用二進位制來描述狀態的一種dp方式,大家都知道,dp是解決多階段決策最優化問題的思想方法,但是有時候階段多了,維度多了,陣列也就爆了,因為雖然維度多,但是有些空間可能用不到,這就很浪費了,(主要是維度多了處理麻煩很噁心)所以我們就把我們就把一組資料壓到乙個int變數裡面(只要是整形,什麼都好啦)
舉個生動形象的例子,在01揹包中,n個物品的選擇方式,就可以用二進位制數來表示:1 0 1 1 0(n=5),從低位開始,表示1不選,2選,3選,4不選,5選。
既然它與二進位制有關,所以我們就需要講一講二進位制啦
名稱
作用
舉例
左移(<<)
位左移運算將整個數按位左移若干位,左移後空出的部分0。
5(101)<<2=20(10100)
右移(>>)
位右移運算將整個數按位右移若干位,右移後空出的部分填0。
5(101)>>2=1(1)
按位與(&)
會將兩個十進位制數在二進位制下進行與運算,然後返回其十進位制下的值。在某一位上,只有兩個數都是1才返回1
5(101)&2(10)=0
按位或(|)
會將兩個十進位制數在二進位制下進行或運算,然後返回其十進位制下的值。在某一位上,只要有乙個數是1就返回1
5(101)|2(10)=7(111)
按位異或(^)
會將兩個十進位制數在二進位制下進行異或運算,然後返回其十進位制下的值。在某一位上,只有兩個數相同才返回1
5(101)^2(10)=0
按位非(~)
把0變成1,1變成0,然後返回其十進位制下的值。
咳咳,最好不要輕易用,因為int有32位(二進位制),前面的全部會變成1
檢查第i位是否是 1
if(1<<(i-1)&x)...
檢查第i位是否是 0
if(1<<(i-1)&x==0)...
統計x中有多少個 1
while(x)
檢查x中是否有相鄰的 1
if(x&(x<<1))...
計算x最低位1代表的值
int lowbit(intx)
把第i位變成 1
x |= (1<<(i-1))
把第i位變成 0
x &= ~(1<<(i-1))
把第i位取反
x ^= (1<<(i-1)
末i位取反
x^(1<<(i-1))
x包含y
if(x&y==y)... or if(x|y==x)...
取右邊連續的1
(x^(x+1))>>1
把右邊連續的0變成1
x&(x-1)
把右邊連續的1變成0
x|(x+1)
把右邊第乙個0變成1
x|(x+1)
這是一道典型的狀壓dp(廢話,學的狀壓不給狀壓給什麼)
我們用乙個m陣列來儲存每一行的情況(土地是否貧瘠),然後用state陣列表示某一種種植方法是否可以滿足任意兩個種植物不相鄰,(bool陣列)。
然後開始一行一行的列舉狀態,如果可用並且沒有貧瘠土地,就列舉上一排的,看不相鄰的情況就轉移,最後把最後一行所有的情況累計起來即可。
code
還是和玉公尺田差不多的操作,但是dp陣列需要加一維,所以就成了在某一行的某種狀態中已經放了x個國王有幾種方法,剩下的就和上乙個例題差不多了
code
奇怪的道路 狀壓DP
小宇從歷史書上了解到乙個古老的文明。這個文明在各個方面高度發達,交通方面也不例外。考古學家已經知道,這個文明在全盛時期有n座城市,編號為1.n。m條道路連線在這些城市之間,每條道路將兩個城市連線起來,使得兩地的居民可以方便地來往。一對城市之間可能存在多條道路。據史料記載,這個文明的交通網路滿足兩個奇...
奇怪的道路(狀壓)
時間限制 1 sec 記憶體限制 128 mb 小宇從歷史書上了解到乙個古老的文明。這個文明在各個方面高度發達,交通方面也不例外。考古學家已經知道,這個文明在全盛時期有n座城市,編號為1.n。m條道路連線在這些城市之間,每條道路將兩個城市連線起來,使得兩地的居民可以方便地來往。一對城市之間可能存在多...
bzoj 3195 奇怪的道路 狀壓dp
看範圍,狀壓沒毛病 但是如果隨便連的話給開1 16,乘上n,m就爆了 所以規定轉移時只向回連邊 於是想狀態陣列 f i j 表示到i這裡i前k位的狀態為j 表示奇偶 發現有條數限制,但是n,m,2 k都比較小,加一維,f i j k 表示前i位,用j條路,i前的k位狀態為j 轉移的話,因為1 u v...