zoukankan      html  css  js  c++  java
  • 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 }
    View Code
  • 相关阅读:
    Is It A Tree?(并查集)(dfs也可以解决)
    【转】python中查询某个函数的使用方法
    python2和python3 print输出不换行
    Python在Windows下列出所有的安装包和模块
    构建打包发布模块及导入使用
    Python保存时提示“SyntaxError: Non-ASCII character 'xe8' in file”
    python基础学习(一)
    命令别名设定:alias,unalias 历史命令:history
    变量内容的删除、取代与替换(optional)
    变量键盘读取、数组与宣告:read,array,declare
  • 原文地址:https://www.cnblogs.com/mrclr/p/9629676.html
Copyright © 2011-2022 走看看