題目鏈結 題意
給出n*m的方格,有些格仔不能鋪線,其它格仔必須鋪,形成乙個閉合迴路。問有多少種鋪法?
思路比賽時基本做不出來,就學個新演算法玩玩。
學習鏈結
**對於我這個不會hash_table 的不太友好,先自己封裝了乙個用著舒服的hash_table,當然也可以直接用stl裡的unordered_map
,初學演算法我認為直接使用後者更好,循序漸進。
插頭dp簡單的說還是輪廓線的狀壓dp?,多考慮了一種連通性問題。
用括號表示法表示輪廓線後,然後考慮狀態轉移。
列舉每點,考慮左邊的朝右插頭r
,上邊朝下插頭d
,左插頭1表示,右插頭2表示
所有的情況就這麼多,然後每點考慮插頭形狀轉移即可
乙個坑點| ^
運算子優先順序不同,不是從左到右運算,然後找了半天bug,還是用+ -
比較穩。
**stl unordered_map
**991ms
吸氧後 228ms
#include
using
namespace std;
#define ll long long
unordered_map dp[3]
;// chatou 0 null, 1 right, 2 down
ll n, m, endx, endy, a[15]
[15], bit[15]
;#define prel (1ll<#define prer (1llsolve()
elseif(
!r &&
!d)else
if(r &&
!d)elseif(
!r && d)
else
if(r ==
1&& d ==1)
}}else
if(r ==
2&& d ==2)
}}else
if(r ==
2&& d ==1)
else
if(r ==
1&& d ==2)
}}}printf
("%lld\n"
,ans);}
intmain()
}}for(ll i =
1; i <=13;
++i) bit[i]
= i<<1;
solve()
;return0;
}
手寫hash_table
**577ms
吸氧後 562ms
#include
using
namespace std;
#define ll long long
struct hash_table
ll ins
(ll sta, ll val)
state[
++up]
= sta;
ans[up]
= val;
nxt[
++tot]
= first[key]
; w[tot]
= up;
first[key]
= tot;
return val;
}}dp[2]
;/*hash_table*/
// chatou 0 null, 1 right, 2 down
ll n, m, endx, endy, a[15]
[15], bit[15]
;#define prel (1ll<#define prer (1llsolve()
elseif(
!r &&
!d)else
if(r &&
!d)elseif(
!r && d)
else
if(r ==
1&& d ==1)
}}else
if(r ==
2&& d ==2)
}}else
if(r ==
2&& d ==1)
else
if(r ==
1&& d ==2)
}}}printf
("%lld\n"
,ans);}
intmain()
}}for(ll i =
1; i <=13;
++i) bit[i]
= i<<1;
solve()
;return0;
}
P5056 模板 插頭dp
插頭dp的模板 插頭dp括號序列的方法其實就是利用迴路不能交叉匹配,必定兩兩配對的性質通過括號序列描述了連通塊的匹配關係 注意分類討論 判斷狀態合法 最邊上一圈不能有插頭延伸過去,要注意 include include include define int long long using names...
P5056 模板 插頭dp
給出n m的方格,有些格仔不能鋪線,其它格仔必須鋪,形成乙個閉合迴路。問有多少種鋪法?第1行,n,m 2 n,m 12 從第2行到第n 1行,每行一段字串 m個字元 表不能鋪線,表必須鋪 輸出乙個整數,表示總方案數 4 4 2none 插頭dp本來以為多niubility的演算法原來本質還是個dp,...
P5056 模板 插頭dp
n m 的網格,求有多少條迴路可以鋪滿整個棋盤。插頭 dp 的,寫法是按照題解上的寫法。狀態用的是括號匹配,然後用了雜湊 鄰接表 掛表 還有滾動陣列優化空間 然後可以看題解學 include include includeusing namespace std const int p 133331 ...