您的位置:首页 > 其它

LianLianKan - HDU 4272(状态压缩)

2015-09-30 15:16 387 查看
题目大意:有一列数据,可以从最上面的开始连接下面相同的元素,然后消除,不过距离不能超过6,询问最后能不能消除完整个数列。

分析:首先讨论一点最远能消除的地方,比如点的位置是x,如若想要消除x+1位置处的值,那么至少也得在x-4处开始消除,所以x后面最多能有4个被消除,也就是最多能下落4个位置,能够消除的最远距离是x+9,不会超过10个状态,所以可以使用状态压缩做,不过有几点还是要注意的,首先输入的数据是从栈底到栈顶的,其次,判断状态的能否达到的时候要注意判断中间有多少个已经被消除的。

代码如下:

======================================================================================================================

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;

const int MAXN = 1<<10;
const int bit = 9;

int data[MAXN];
bool dp[MAXN][MAXN];

int main()
{
int i, j, k, N;

while(scanf("%d", &N) != EOF)
{
memset(data, -1, sizeof(data));
memset(dp, 0, sizeof(dp));

for(i=N; i>0; i--)
{
scanf("%d", &data[i]);
}

dp[0][0] = true;

for(i=1; i<=N; i++)
for(j=0; j<MAXN; j++)
{
if(dp[i-1][j] == true)
{///这种状态存在
if(j & 1)
{///本位已经被消除
dp[i][j>>1] = true;
}
else
{
int t = 0;///纪录已经被消除的,状态1表示被消除,0表示没有

for(k=1; k<=bit; k++)
{
if(!(j&(1<<k)) && k-t <=5 &&data[i] == data[i+k])
{///可以消除,两者之间的距离应该不超过6
dp[i][(j>>1)|(1<<(k-1))] = true;
}
else if(j & (1<<k))
t++;
}
}
}
}

if(dp
[0] == true)
printf("1\n");
else
printf("0\n");
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: