http://acm.hdu.edu.cn/showproblem.php?pid=4272
题意:
题意:长度为n(n<=1000)的栈,栈顶元素可以与下面1~5个数中相同的元素消去,问最后能都完全消去。
题解:
状态压缩 dp 如何判断一个 物品 是否可以 被删除 ,首先 最坏的 情况是 2 0 0 0 0 1 1 1 1 2 假如我们要消除 栈顶的 2 ,0表示已经被删除了。
我们要 知道 包括 本身在内的 10 个 数位
dp[h][i] 表示 高度 为 h 状态 为 i 能否 全部 消除 1 表示可以 0表示 不可以
1 #include<cstdio>
2 #include<cstring>
3 #include<cmath>
4 #include<iostream>
5 #include<algorithm>
6 #include<
set>
7 #include<map>
8 #include<queue>
9 #include<vector>
10 #include<
string>
11
#define Min(a,b) a<b?a:b
12
#define Max(a,b) a>b?a:b
13
#define CL(a,num) memset(a,num,sizeof(a));
14
#define eps 1e-12
15
#define inf 0x7fffffff
16
17
//
freopen("data.txt","r",stdin);
18
const
double pi = acos(-
1.0);
19 typedef __int64 ll;
20
const
int maxn =
1200 ;
21
using
namespace std;
22
int dp[maxn][maxn],a[maxn];
23
int dfs(
int h,
int tmp)
24 {
25
26
int i,j ,k;
27
if( h <
0)
28 {
29
if(tmp ==
0 )
return
1;
30
else
return
0 ;
31 }
32
if(dp[h][tmp]!=-
1)
return dp[h][tmp] ;
33
int &ret = dp[h][tmp] ;
34
35
int t = (
1<<
9)& tmp ;
36 ret =
0;
37
if(!t)
//
如果此位已经 被选过了
38
{
39
int k = tmp <<
1;
40
if(h -
10 >=
0) ret = dfs(h -
1,k +
1);
41
else ret = dfs(h -
1,k);
42 }
43
else
44 {
45
46
int cnt =
0;
47 tmp = tmp^(
1 <<
9);
48
for(i =
1,j =
8;i<=
9,j >=
0;i++,j--)
49 {
50
if(tmp &(
1 << j))
51 {
52 cnt++;
53
54
if(cnt >
5)
break;
55
56
if(a[h] == a[h - i])
57 {
58
int t = tmp^(
1 << j);
59 t<<=
1;
60
if(h -
10>=
0) t +=
1;
61
62 ret = dfs(h -
1,t);
63
if(ret)
break ;
64
65
66 }
67 }
68 }
69 }
70
71
return ret;
72
73
74 }
75
int main()
76 {
77
int n , m,i,j;
78
while(~scanf(
"
%d
",&n))
79 {
80
for(i =
0 ; i<n;i++)
81 scanf(
"
%d
",&a[i]);
82
83
int tp =
0;
84
for(i = n -
1,j =
0;i >=
0&& j <=
9;i--,j++)
85 {
86 tp = (tp <<
1) +
1;
87 }
88
89
while(j <=
9)tp<<=
1,j++ ;
90
91 CL(dp ,-
1);
92
int ans = dfs(n -
1,tp);
93
if(ans)puts(
"
1
");
94
else puts(
"
0
");
95 }
96 }