zoukankan      html  css  js  c++  java
  • HDU 1693 Eat the Trees 插头DP

      这是一道入门题,只需判断插头有无。

      具体分为:

        1、上插头和左插头都有

        2、有上插头或有左插头

        3、上插头和左插头都没有

      用HASHMAP储存状态,具体有一些小技巧(见程序)。

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cstring>
      4 #include <string>
      5 #include <algorithm>
      6 
      7 using namespace std;
      8 
      9 #define REP(i, a, b) for (int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
     10 #define DWN(i, a, b) for (int i = (a), i##_end_ = (b); i >= i##_end_; --i)
     11 #define mset(a, b) memset(a, b, sizeof(a))
     12 typedef long long LL;
     13 const int MAXD = 15, HASH = 10007, STATE = 100010;
     14 int n, m, maze[MAXD][MAXD];
     15 int code[MAXD];
     16 struct HASHMAP
     17 {
     18     int head[HASH], nxt[STATE], siz, state[STATE]; LL f[STATE];
     19     void clear() { siz = 0, mset(head, -1); }
     20     void push(int x, LL add)
     21     {
     22         int pos = x%HASH, i = head[pos];
     23         for (; i != -1; i = nxt[i])
     24             if (state[i] == x)
     25             { f[i] += add; return ; }
     26         state[siz] = x, f[siz] = add;
     27         head[pos] = siz, nxt[siz++] = head[pos];    
     28     }
     29 }hm[2];
     30 
     31 void in()
     32 {
     33     scanf("%d %d", &n, &m), mset(maze, 0);
     34     REP(i, 1, n)
     35         REP(j, 1, m) scanf("%d", &maze[i][j]);
     36 }
     37 
     38 void decode(int s)
     39 {
     40     REP(i, 0, m)
     41         if (s&(1<<i)) code[i] = 1;
     42         else code[i] = 0;
     43 }
     44 
     45 int encode()
     46 {
     47     int ret = 0;
     48     DWN(i, m, 0) ret = ret*2+code[i];
     49     return ret;
     50 }
     51 
     52 void shift(int j) 
     53 { 
     54     if (j != m) return ;
     55     DWN(i, m, 1) code[i] = code[i-1]; code[0] = 0;
     56 }
     57 
     58 void dp_blank(int i, int j, int cur)
     59 {
     60     REP(k, 0, hm[cur].siz-1)
     61     {
     62         decode(hm[cur].state[k]);
     63         int lef = code[j-1], up = code[j];
     64         if (lef && up)
     65         {
     66             code[j-1] = code[j] = 0, shift(j);
     67             hm[cur^1].push(encode(), hm[cur].f[k]);
     68         }
     69         else
     70         {
     71             if (lef || up)
     72             {
     73                 if (maze[i+1][j])
     74                 {
     75                     code[j-1] = 1, code[j] = 0, shift(j);
     76                     hm[cur^1].push(encode(), hm[cur].f[k]);
     77                 }
     78                 if (maze[i][j+1])
     79                 {
     80                     code[j-1] = 0, code[j] = 1;
     81                     hm[cur^1].push(encode(), hm[cur].f[k]);
     82                 }
     83             }
     84             else
     85                 if (maze[i+1][j] && maze[i][j+1])
     86                 {
     87                     code[j-1] = code[j] = 1, shift(j);
     88                     hm[cur^1].push(encode(), hm[cur].f[k]);
     89                 }
     90         }
     91     }
     92 }
     93 
     94 void dp_block(int i, int j, int cur)
     95 {
     96     REP(k, 0, hm[cur].siz-1)
     97     {
     98         decode(hm[cur].state[k]);
     99         code[j-1] = code[j] = 0, shift(j);
    100         hm[cur^1].push(encode(), hm[cur].f[k]);
    101     }
    102 }
    103 
    104 void work()
    105 {
    106     int cur = 0; LL ans = 0;
    107     hm[0].clear(), hm[0].push(0, 1);
    108     REP(i, 1, n)
    109         REP(j, 1, m)
    110         {
    111             hm[cur^1].clear();
    112             if (maze[i][j]) dp_blank(i, j, cur);
    113             else dp_block(i, j, cur);
    114             cur ^= 1;
    115         }
    116     REP(i, 0, hm[cur].siz-1) ans += hm[cur].f[i];
    117     printf("There are %I64d ways to eat the trees.
    ", ans);
    118 }
    119 
    120 int main()
    121 {
    122     int T;
    123     scanf("%d", &T);
    124     REP(i, 1, T)
    125     {
    126         printf("Case %d: ", i);
    127         in(), work();
    128     }
    129     return 0;
    130 }
    View Code
  • 相关阅读:
    虚幻4目录文件结构
    虚幻4编译手记
    几个重要的坐标系
    关于(void**)及其相关的理解
    装饰器总结篇(持续更新ing)
    Linux中find常见用法示例
    linux grep命令
    linux下IPTABLES配置详解
    分布式数据库中间件DDM的实现原理
    消息队列应用场景解析
  • 原文地址:https://www.cnblogs.com/-ZZB-/p/6435051.html
Copyright © 2011-2022 走看看