LianLianKan
I like playing game with my friend, although sometimes looks pretty naive. Today I invent a new game called LianLianKan. The game is about playing on a number stack.
Now we have a number stack, and we should link and pop the same element pairs from top to bottom. Each time, you can just link the top element with one same-value element. After pop them from stack, all left elements will fall down. Although the game seems to be interesting, it's really naive indeed.
To prove I am a wisdom among my friend, I add an additional rule to the game: for each top element, it can just link with the same-value element whose distance is less than 6 with it.
Before the game, I want to check whether I have a solution to pop all elements in the stack.
Input
There are multiple test cases.
The first line is an integer N indicating the number of elements in the stack initially. (1 <= N <= 1000)
The next line contains N integer ai indicating the elements from bottom to top. (0 <= ai <= 2,000,000,000)
Output
For each test case, output “1” if I can pop all elements; otherwise output “0”.
Sample Input
2 1 1 3 1 1 1 2 1000000 1
Sample Output
1 0 0
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4272
题目大意:连连看,给出从下到上的n个块,从栈顶开始消,只能连距离小于6的
思路:dp[ i ] [ j ] 表示栈顶为 i ,状态为 j ,状态表示的是栈顶下面的9个是否被消掉,0表示没消掉,1表示消掉了。因为能消掉距离小于6的,所以下面1-4个都可能被之前的消掉了,所以最远可以到9
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long
const int N=1005;
ll a[N],dp[N][1<<10];
void dfs(int x,int y)
{
int cnt=0;
for(int i=9,j=1;i>=0;i--,j++)
{
if((y&(1<<i))==0) //没被消掉
{
cnt++;
if(a[x]==a[x+j])
{
int tmp=(y|(1<<i));
dp[x][tmp]=1;
}
}
if(cnt==5) break;//距离大于5的不管
}
}
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(a,0,sizeof(a));
for(int i=n;i>0;i--) scanf("%lld",&a[i]),a[i]++;
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=1;i<n;i++)
{
for(int j=0;j<(1<<10);j++)
{
if(!dp[i-1][j]) continue;
if(j&(1<<9)) //如果第i位已经被消掉了
{
int x=(j-(1<<9))<<1;
dp[i][x]=1;
}
else dfs(i,j<<1);
}
}
printf("%d\n",dp[n-1][1<<9]);
}
return 0;
}