LianLianKan HDU - 4272 状压dp

题意:长度为n(n<=1000)的栈,栈顶元素可以与下面1~5个数中相同的元素消去,问最后能都完全消去。

 

题解:

比如这个序列
1
2
3
4
5
6
7
8
9
10
11
2这个位置的最远可匹配位置能到11
为什么呢?
因为1这个位置可以匹配到6,那也就是说3、4、5、6这几个位置都可能被上面的匹配过(我写的序列肯定不够,将就一下)
那么剩下的序列就变成了
2
7
8
9
10
11
这样的话2的最远匹配距离就是11了
所以我们要保存至少9个位置的状态,因为我们只需要确保这个位置的数是否呗抵消过
所以我们可以用1代表这个位置的数已经被抵消了,0代表没有被抵消
然后把这九个状态当作二进制形式,然后就被压缩成了一个int大小数字
所以最开始状态就是dp[0][0]=1
dp[i][j]的值代表距离栈顶i-1的那个位置的数是否被抵消,是1代表被抵消了,是0代表没有抵消
dp[0][0]的设定只是为了下面程序的运行
因为题目保证首先要抵消栈顶的元素,所以我们每给dp[i][]赋值的时候必须要确保,dp[i-1][]某个位置的值是1
具体看代码
 
 
代码:
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<iostream>
 4 #include<algorithm>
 5 typedef long long ll;
 6 using namespace std;
 7 const int maxn=1005;
 8 const int M=1<<9;
 9 int v[maxn],dp[maxn][1<<9];
10 int main()
11 {
12     int n;
13     while(~scanf("%d",&n))
14     {
15         memset(dp,0,sizeof(dp));
16         for(int i=n;i>0;--i)
17             scanf("%d",&v[i]);
18         dp[0][0]=1;
19         for(int i=1;i<=n;++i)
20         {
21             for(int j=0;j<M;++j)
22             {
23                 if(dp[i-1][j]) //因为题目说明要先抵消栈顶的元素,所以每一次寻找都要找到上一个元素被抵消的位置
24                 {
25                     if(j&1) //这个判断是用来判断这个位置的数字是不是被它上一个位置消掉了
26                     {
27                         dp[i][j>>1]=1;  //因为j这个状态压缩的是它下面10个位置的状态,所以j>>1就完了
28                     }
29                     else
30                     {
31                         int t=0; //记录这个位置实际上下沉了几个位置
32                         for(int k=1;k<=8;++k)
33                         {
34                             if(!(j&(1<<k)) && k-t<=5 && v[i]==v[i+k])
35                             {
36                                 dp[i][(j>>1)|(1<<(k-1))]=1;
37                             }
38                             else if(j&(1<<k))
39                                 t++;
40                         }
41                     }
42                 }
43             }
44         }
45         if(dp[n][0]==1)
46             printf("1\n");
47         else printf("0\n");
48     }
49     return 0;
50 }

 

posted @ 2019-12-23 09:01  kongbursi  阅读(113)  评论(0编辑  收藏  举报