【HDOJ】4363 Draw and paint

看题解解的。将着色方案映射为40*40*5*5*5*5*2个状态,40*40表示n*m,5*5*5*5表示上下左右相邻块的颜色,0表示未着色。
2表示横切或者竖切。
基本思路是记忆化搜索然后去重,关键点是可能未切前当前块已经着色了。

  1 /* 4363 */
  2 #include <iostream>
  3 #include <sstream>
  4 #include <string>
  5 #include <map>
  6 #include <queue>
  7 #include <set>
  8 #include <stack>
  9 #include <vector>
 10 #include <deque>
 11 #include <algorithm>
 12 #include <cstdio>
 13 #include <cmath>
 14 #include <ctime>
 15 #include <cstring>
 16 #include <climits>
 17 #include <cctype>
 18 #include <cassert>
 19 #include <functional>
 20 #include <iterator>
 21 #include <iomanip>
 22 using namespace std;
 23 //#pragma comment(linker,"/STACK:102400000,1024000")
 24 
 25 #define sti                set<int>
 26 #define stpii            set<pair<int, int> >
 27 #define mpii            map<int,int>
 28 #define vi                vector<int>
 29 #define pii                pair<int,int>
 30 #define vpii            vector<pair<int,int> >
 31 #define rep(i, a, n)     for (int i=a;i<n;++i)
 32 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 33 #define clr                clear
 34 #define pb                 push_back
 35 #define mp                 make_pair
 36 #define fir                first
 37 #define sec                second
 38 #define all(x)             (x).begin(),(x).end()
 39 #define SZ(x)             ((int)(x).size())
 40 #define lson            l, mid, rt<<1
 41 #define rson            mid+1, r, rt<<1|1
 42 
 43 const int mod = 1e9+7;
 44 int dp[41][41][5][5][5][5][2];
 45 
 46 int calc(int x, int y, int u, int d, int l, int r, int dir) {
 47     if (dp[x][y][u][d][l][r][dir] >= 0)
 48         return dp[x][y][u][d][l][r][dir];
 49     
 50     int& ret = dp[x][y][u][d][l][r][dir];
 51     
 52     ret = 0;
 53     if ((x==1&&dir==0) || (y==1&&dir==1)) {
 54         rep(i, 1, 5)
 55             if (i!=u && i!=d && i!=l && i!=r)
 56                 ++ret;
 57         return ret;
 58     }
 59     
 60     if (dir) {
 61         rep(i, 1, y) {
 62             rep(j, 1, 5) {
 63                 if (j!=u && j!=d && j!=l) {
 64                     ret = (ret + calc(x, y-i, u, d, j, r, 0)) % mod;
 65                 }
 66                 if (j!=u && j!=d && j!=r) {
 67                     ret = (ret + calc(x, i, u, d, l, j, 0)) % mod;
 68                 }
 69             }
 70         }
 71         
 72         int tmp = 0;
 73         rep(i, 1, 5) {
 74             if (i!=u && i!=d && i!=l) {
 75                 rep(j, 1, 5) {
 76                     if (j!=u && j!=d && j!=r && j!=i)
 77                         ++tmp;
 78                 }
 79             }
 80         }
 81         
 82         ret = (ret + mod - tmp*(y-1)) % mod;
 83         rep(i, 1, 5)
 84             if (i!=u && i!=l && i!=r && i!=d)
 85                 ++ret;
 86             
 87         ret %= mod;
 88     } else {
 89         rep(i, 1, x) {
 90             rep(j, 1, 5) {
 91                 if (j!=u && j!=l && j!=r) {
 92                     ret = (ret + calc(x-i, y, j, d, l, r, 1)) % mod;
 93                 }
 94                 if (j!=d && j!=l && j!=r) {
 95                     ret = (ret + calc(i, y, u, j, l, r, 1)) % mod;
 96                 }
 97             }
 98         }
 99         
100         int tmp = 0;
101         rep(i, 1, 5) {
102             if (i!=u && i!=l && i!=r) {
103                 rep(j, 1, 5) {
104                     if (j!=d && j!=l && j!=r && j!=i)
105                         ++tmp;
106                 }
107             }
108         }
109         
110         ret = (ret + mod - tmp*(x-1)) % mod;
111         rep(i, 1, 5)
112             if (i!=u && i!=l && i!=r && i!=d)
113                 ++ret;
114             
115         ret %= mod;
116     }
117     
118     return ret;
119 }
120 
121 int main() {
122     ios::sync_with_stdio(false);
123     #ifndef ONLINE_JUDGE
124         freopen("data.in", "r", stdin);
125         freopen("data.out", "w", stdout);
126     #endif
127     
128     int t;
129     int n, m;
130     int ans;
131     
132     memset(dp, -1, sizeof(dp));
133     scanf("%d", &t);
134     while (t--) {
135         scanf("%d %d", &n, &m);
136         ans = calc(n, m, 0, 0, 0, 0, 0);
137         printf("%d\n", ans);
138     }
139     
140     #ifndef ONLINE_JUDGE
141         printf("time = %d.\n", (int)clock());
142     #endif
143     
144     return 0;
145 }

 

你可能感兴趣的:(【HDOJ】4363 Draw and paint)