POJ 1038 Bugs Integrated, Inc.
Posted mrclr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 1038 Bugs Integrated, Inc.相关的知识,希望对你有一定的参考价值。
看这种图上摆放方案的题,以及 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 }
以上是关于POJ 1038 Bugs Integrated, Inc.的主要内容,如果未能解决你的问题,请参考以下文章
POJ 1038 Bugs Integrated, Inc.
POJ1038 Bugs Integrated, Inc 状压DP+优化