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 }
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 }