PKU1038,动态规划,用的三进制压缩状态(不知道和二进制那个快,毕竟计算机这个东西是二进制的),感觉没用的状态有点多,所以改成了记忆化搜索,另外第一次排到了速度的23名。。

PKU1038
1
/**//*
2
Task: pku1038
3
Author: DMKaplony
4
Date: 01/03/2010 18:51:04 China Standard Time
5
State: AC @ 03/03/2010 09:04:19 China Standard Time
6
Speed 23
7
Memo: DP--Forxcc0322
8
*/
9
10
#include <iostream>
11
12
#define INF 0x7FFFFFFF
13
#define gmax(a,b) ((a)>(b)?(a):(b))
14
#define MAXN 400
15
#define MAXM 11
16
#define MAXS 177147
17
18
using namespace std;
19
20
struct QNode
{
21
int row;
22
int state;
23
int f;
24
void SetData(int R, int S, int F)
{
25
row = R;
26
state = S;
27
f = F;
28
}
29
};
30
31
QNode Q[MAXS];
32
int h, t, maxq;
33
bool block[MAXN][MAXM];
34
int pnt[2][MAXS];
35
int n, m, k;
36
int v[MAXM];
37
int x;
38
int state;
39
int ans;
40
41
void DfsExtend(int dep, int got)
{
42
if (!dep)
{
43
int newstate = 0;
44
for (int i=m; i; i--)
{
45
newstate *= 3;
46
newstate += v[i] - 1;
47
}
48
if (x < n && pnt[(x + 1)& 1][newstate] == -1)
{
49
if (++t == maxq)
50
t = 0;
51
Q[t].SetData(x + 1, newstate, got);
52
pnt[(x + 1)& 1][newstate] = t;
53
}
54
else
55
if (got > Q[pnt[(x + 1)& 1][newstate]].f)
56
Q[pnt[(x + 1)&1][newstate]].f = got;
57
return;
58
}
59
if (dep >= 3 && !v[dep] && !v[dep - 1] && !v[dep - 2])
{
60
if (block[x + 2][dep])
61
v[dep] = 3;
62
else
63
v[dep] = 2;
64
if (block[x + 2][dep - 1])
65
v[dep - 1] = 3;
66
else
67
v[dep - 1] = 2;
68
if (block[x + 2][dep - 2])
69
v[dep - 2] = 3;
70
else
71
v[dep - 2] = 2;
72
73
DfsExtend(dep - 3, got + 1);
74
75
v[dep] = v[dep - 1] = v[dep - 2] = 0;
76
}
77
if (dep >= 2 && !block[x + 2][dep] && !block[x + 2][dep - 1]
78
&& !v[dep] && !v[dep - 1])
{
79
v[dep] = 3;
80
v[dep - 1] = 3;
81
82
DfsExtend(dep - 2, got + 1);
83
84
v[dep] = v[dep - 1] = 0;
85
}
86
//
87
if (block[x + 2][dep])
{
88
int tmp = v[dep];
89
v[dep] = 3;
90
DfsExtend(dep - 1, got);
91
v[dep] = tmp;
92
}
93
else
94
if (!v[dep])
{
95
v[dep] = 1;
96
DfsExtend(dep - 1, got);
97
v[dep] = 0;
98
}
99
else
{
100
DfsExtend(dep - 1, got);
101
}
102
}
103
104
105
void Extend(int x, int state, int got)
{
106
memset(v, 0, sizeof(v));
107
while (state)
{
108
v[++v[0]] = state % 3;
109
state /= 3;
110
}
111
DfsExtend(m, got);
112
}
113
114
int QPow(int x, int y)
{
115
if (y == 0)
116
return 1;
117
else
118
if (y == 1)
119
return x;
120
int tmp = QPow(x, y >> 1);
121
tmp *= tmp;
122
if (y & 1)
123
return tmp * x;
124
else
125
return tmp;
126
}
127
int main()
{
128
int cases;
129
scanf("%d", &cases);
130
while (cases--)
{
131
scanf("%d %d %d", &n, &m, &k);
132
memset(block, 0, sizeof(block));
133
134
int i;
135
for (i=1; i<k+1; i++)
{
136
int x, y;
137
scanf("%d %d", &x, &y);
138
block[x][y] = true;
139
}
140
for (i=1; i<m+1; i++)
{
141
block[n + 1][i] = true;
142
}
143
144
memset(pnt, 0xFF, sizeof(pnt));
145
int newstate = 0;
146
for (int j=m; j; j--)
{
147
newstate *= 3;
148
if (block[2][j])
149
newstate += 2;
150
else
151
if (block[1][j])
152
newstate += 1;
153
}
154
ans = 0;
155
h = 0;
156
t = 0;
157
maxq = QPow(3, m + 2);
158
if (++t == maxq)
159
t = 0;
160
Q[t].SetData(1, newstate, 0);
161
pnt[1][newstate] = t;
162
x = 1;
163
while (h != t)
{
164
if (++h == maxq)
165
h = 0;
166
if (x != Q[h].row)
{
167
memset(pnt[(x + 1)&1], 0xFF, sizeof(pnt[(x + 1)& 1]));
168
x++;
169
}
170
state = Q[h].state;
171
ans = gmax(ans, Q[h].f);
172
Extend(x, state, Q[h].f);
173
}
174
printf("%d\n", ans);
175
}
176
return 0;
177
}
178