poj 2663 Tri Tiling (狀壓dp+多米諾骨牌問題+滾動陣列反思)
阿新 • • 發佈:2018-12-11
本來直接一波狀壓dpAC的
#include<cstdio> #include<cstring> #include<algorithm> #define REP(i, a, b) for(int i = (a); i < (b); i++) #define _for(i, a, b) for(int i = (a); i <= (b); i++) using namespace std; typedef long long ll; ll dp[50][10]; int path[15][2], p, n, m = 3; void dfs(int l, int now, int pre) { if(l > m) return; if(l == m) { path[p][0] = pre; path[p++][1] = now; return; } dfs(l + 1, (now << 1) | 1, pre << 1); dfs(l + 1, now << 1, (pre << 1) | 1); dfs(l + 2, (now << 2) | 3, (pre << 2) | 3); } int main() { dfs(0, 0, 0); while(~scanf("%d", &n) && n != -1) { memset(dp, 0, sizeof(dp)); dp[0][(1 << m) - 1] = 1; _for(i, 1, n) REP(j, 0, p) dp[i][path[j][1]] += dp[i-1][path[j][0]]; printf("%lld\n", dp[n][(1 << m) - 1]); } return 0; }
然後閒著無聊想用滾動陣列優化一下,雖然說對於這道題完全沒必要
然後就發現了問題
每次使用的時候要清空這一行的值
因為這道題的狀態轉移是+=, 以前都是=,所以值可以直接覆蓋。
#include<cstdio> #include<cstring> #include<algorithm> #define REP(i, a, b) for(int i = (a); i < (b); i++) #define _for(i, a, b) for(int i = (a); i <= (b); i++) using namespace std; typedef long long ll; ll dp[2][10]; int path[15][2], p, n, m = 3; void dfs(int l, int now, int pre) { if(l > m) return; if(l == m) { path[p][0] = pre; path[p++][1] = now; return; } dfs(l + 1, (now << 1) | 1, pre << 1); dfs(l + 1, now << 1, (pre << 1) | 1); dfs(l + 2, (now << 2) | 3, (pre << 2) | 3); } int main() { dfs(0, 0, 0); while(~scanf("%d", &n) && n != -1) { memset(dp, 0, sizeof(dp)); int t = 0; dp[t][(1 << m) - 1] = 1; t ^= 1; _for(i, 1, n) { REP(j, 0, p) dp[t][path[j][1]] = 0; //這一行是關鍵 REP(j, 0, p) dp[t][path[j][1]] += dp[t^1][path[j][0]]; t ^= 1; } printf("%lld\n", dp[t^1][(1 << m) - 1]); } return 0; }