小宇從歷史書上了解到乙個古老的文明。這個文明在各個方面高度發達,交通方面也不例外。
考古學家已經知道,這個文明在全盛時期有n座城市,編號為1..n。m條道路連線在這些城市之間,每條道路將兩個城市連線起來,使得兩地的居民可以方便地來往。
一對城市之間可能存在多條道路。 據史料記載,這個文明的交通網路滿足兩個奇怪的特徵。
首先,這個文明崇拜數字k,所以對於任何一條道路,設它連線的兩個城市分別為u和v,則必定滿足1 <=|u - v| <= k。此外,任何乙個城市都與恰好偶數條道路相連(0也被認為是偶數)。
不過,由於時間過於久遠,具體的交通網路我們已經無法得知了。
小宇很好奇這n個城市之間究竟有多少種可能的連線方法,於是她向你求助。
方法數可能很大,你只需要輸出方法數模1000000007後的結果。
100%的資料滿足1 <= n <= 30, 0 <= m <= 30, 1 <= k <= 8.
簡化版題意:n個點m條邊,滿足條件:
每個點的度為偶數。
每條邊連線的頂點u,v編號之差不超過k且沒有自環。
求方案數%
1000000007後的值。
挺神的一道狀壓$dp$題。難點在於狀態量的表示。首先我們分析資料範圍,發現$k<=8$,那麼很顯然狀態壓縮的那一維和k有關,也是我們直接想到狀壓$dp$的乙個原因。
那麼有$f[i][j][s]$表示前$i$個點,連了$j條邊,編號為i-k->i$的點的狀態為$s$,那麼顯然$s$表示的是這些點度數的奇偶性。
然後快樂的開始推。考慮加入一條邊的狀態轉移。然
後,就沒有然後了。。。。。。(本人做此題也就到此為止了)
怎麼加邊?以$i$為乙個端點,另乙個呢?很顯然這個狀態不足以滿足$dp$轉移,我們需要再加一維,表示當前的$i$向哪個點連邊。又因為頂點編號之差$<=k$,我們只需要考慮$i向區間[i-k,i-1]$的連邊就可以了。那麼有$f[i][j][s][l]表示前i個點,連了j條邊,[i-k,i]的狀態為s,處理當前點i和i-k+l$之間的連邊。
轉移不是特別難(這裡採用刷表):
$i和i-k+l不連邊,有f[i][j][s][l+1]+=f[i][j][s][l]$
$i和i-k+l$連邊,有$f[i][j+1][s$ $ \oplus$ $1<
考慮增加乙個點,那麼必須有:編號為$i-k$的點度數為偶數,$[i-k,i-1]$區間的點和i已經全部轉移
答案就是$f[n][m][0][k]$前$n$個點連線了$m$條邊,當且處理的是$n-k+k=n$,即$[n-k,n-1]$全部處理完的情況。
#includeusingnamespace
std;
const
int p=1000000007
;const
int s=1
<<9
;int f[35][35][s][35
];int
n,m,k;
intmain()
if(!(s&1))f[i+1][j][s>>1][0]+=f[i][j][s][k]%=p;//
把i-k刪去,加入i+1
} cout
<0
][k];
}
奇怪的道路(狀壓)
時間限制 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...
狀壓DP 奇怪的東西
狀態壓縮動態規劃 簡稱狀壓dp 是非常典型的一類dp。他是利用二進位制來描述狀態的一種dp方式,大家都知道,dp是解決多階段決策最優化問題的思想方法,但是有時候階段多了,維度多了,陣列也就爆了,因為雖然維度多,但是有些空間可能用不到,這就很浪費了,主要是維度多了處理麻煩很噁心 所以我們就把我們就把一...