1. 程式人生 > >POJ 1038 Bugs Integrated, Inc.

POJ 1038 Bugs Integrated, Inc.

vector bug ems code close ret 因此 spa tin

嘟嘟嘟

看這種圖上擺放方案的題,以及 m <= 10,就一定能猜到是狀壓dp。

考慮當前第 i 行放一個3 * 2的方塊,只會受到 i - 1行和 i - 2行的影響,

所以設:0:表示上兩行都空閑。

    1:i - 2行有塊,i - 1行空閑。

    2:i - 1行有塊,因此 i - 2行的狀態就不用管了。

因此用一個三進制數表示當前行的狀態。

然後對於這一個塊是壞的,也標記為2就行了。

令dp[i][j]表示第 i 行狀態為 j 時最多能放的塊的個數,令shap[0 / 1][j]表示上一行/上上一行第 j 列的狀態,然後對於每一次循環,我們先更新shap,在用dfs,枚舉當前這一行合法的放置狀態,同時更新dp.

需要註意的是,這樣dp會MLE,又因為當前狀態只和上兩行有關,因此用滾動數組優化就能AC了。

說起來好像還行,但其實寫起來挺麻煩的,而且難度還不小,應該有省選難度吧……

技術分享圖片
  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cmath>
  4 #include<algorithm>
  5 #include<cstring>
  6 #include<cstdlib>
  7 #include<cctype>
  8 #include<vector>
  9
#include<stack> 10 #include<queue> 11 using namespace std; 12 #define enter puts("") 13 #define space putchar(‘ ‘) 14 #define Mem(a, x) memset(a, x, sizeof(a)) 15 typedef long long ll; 16 typedef double db; 17 const int INF = 0x3f3f3f3f; 18 const db eps = 1e-8; 19 const int maxn = 155
; 20 const int maxm = 6e4 + 5; 21 inline ll read() 22 { 23 ll ans = 0; 24 char ch = getchar(), last = ; 25 while(!isdigit(ch)) {last = ch; ch = getchar();} 26 while(isdigit(ch)) {ans = ans * 10 + ch - 0; ch = getchar();} 27 if(last == -) ans = -ans; 28 return ans; 29 } 30 inline void write(ll x) 31 { 32 if(x < 0) x = -x, putchar(-); 33 if(x >= 10) write(x / 10); 34 putchar(x % 10 + 0); 35 } 36 37 int T, n, m; 38 int bas[maxm], shap[2][maxm]; 39 int dp[2][maxm]; 40 bool Map[maxn][11]; 41 42 void init() 43 { 44 Mem(Map, 0); Mem(dp, -1); Mem(shap, 0); 45 } 46 47 int change_3(int* a) 48 { 49 int ret = 0; 50 for(int i = 1; i <= m; ++i) ret += a[i] * bas[i - 1]; 51 return ret; 52 } 53 void change_10(int x, int* a) 54 { 55 for(int i = 1; i <= m; ++i) a[i] = x % 3, x /= 3; 56 } 57 58 void dfs(int i, int j, int tot) 59 { 60 if(j > m) return; 61 int o = (i + 1) & 1, x = change_3(shap[1]); 62 dp[o ^ 1][x] = max(dp[o ^ 1][x], dp[o][change_3(shap[0])]); 63 if(j < m && !shap[0][j] && !shap[0][j + 1] && !shap[1][j] && !shap[1][j + 1]) 64 { 65 shap[1][j] = shap[1][j + 1] = 2; 66 int p = change_3(shap[1]); 67 dp[o ^ 1][p] = max(dp[o ^ 1][p], tot + 1); 68 dfs(i, j + 2, tot + 1); 69 shap[1][j] = shap[1][j + 1] = 0; 70 } 71 if(j < m - 1 && !shap[1][j] && !shap[1][j + 1] && !shap[1][j + 2]) 72 { 73 shap[1][j] = shap[1][j + 1] = shap[1][j + 2] = 2; 74 int p = change_3(shap[1]); 75 dp[o ^ 1][p] = max(dp[o ^ 1][p], tot + 1); 76 dfs(i, j + 3, tot + 1); 77 shap[1][j] = shap[1][j + 1] = shap[1][j + 2] = 0; 78 } 79 dfs(i, j + 1, tot); 80 81 } 82 83 int main() 84 { 85 bas[0] = 1; 86 for(int i = 1; i <= 10; ++i) bas[i] = (bas[i - 1] << 1) + bas[i - 1]; 87 int T = read(); 88 while(T--) 89 { 90 init(); 91 n = read(); m = read(); 92 int q = read(); 93 for(int i = 1; i <= q; ++i) Map[read()][read()] = 1; 94 for(int i = 1; i <= m; ++i) shap[0][i] = Map[1][i] + 1; 95 dp[1][change_3(shap[0])] = 0; 96 for(int i = 2, o = 1; i <= n; ++i, o ^= 1) 97 { 98 Mem(dp[o ^ 1], -1); 99 for(int j = 0; j < bas[m]; ++j) 100 { 101 if(dp[o][j] == -1) continue; 102 change_10(j, shap[0]); 103 for(int k = 1; k <= m; ++k) 104 { 105 if(Map[i][k]) shap[1][k] = 2; 106 else shap[1][k] = max(shap[0][k] - 1, 0); 107 } 108 dfs(i, 1, dp[o][j]); 109 } 110 } 111 int ans = 0; 112 for(int i = 0; i < bas[m]; ++i) ans = max(ans, max(dp[0][i], dp[1][i])); 113 write(ans); enter; 114 115 } 116 return 0; 117 }
View Code

POJ 1038 Bugs Integrated, Inc.