LianLianKan - HDU 4272(状态压缩)

题目大意:有一列数据,可以从最上面的开始连接下面相同的元素,然后消除,不过距离不能超过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[N][0] == true)
            printf("1\n");
        else
            printf("0\n");
    }

    return 0;
}
时间: 2024-12-27 22:58:09

LianLianKan - HDU 4272(状态压缩)的相关文章

hdu 5180 状态压缩 dp 打表

hdu 5180 状态压缩 dp 打表 题意: 在n*n的国际象棋中,放置若干个国王和k个车,使得国王之间不互相攻击,车之间不互相攻击,车不可攻击到国王(这并不代表国王不能攻击到车).国王能攻击到它上下左右,左上左下右上右下八个位置的棋子,车可以攻击到同一行或同一列中的棋子,求方案总数对1000000007取模后的值. 限制: 1 <= n <=15; 0 <= k <=15 思路: 状态压缩,dp,打表套打表 打表程序如下: 打表程序1: tab[a][b]表示a*b的棋盘王的放

hdu 4917Permutation(状态压缩DP)

hdu 4917Permutation(状态压缩DP) 题意:将1~n的n个数排列成序列(n<=40),但有m(m<=20)个限制条件,其中第i个限制条件的表示为ai,bi.表示该序列的第ai的数要小于第bi的.问有多少中排列?保证有解 解法:我们首先可以明确一点,这m个限制条件,所表示的关系会构成若干个DAG(有向无环图,我将其称之为拓扑图).我们只要将这n个数,填入到拓扑图上,使其满足拓扑关系,那么这样的序列就是可以的.而这若干个拓扑图之间,是不会相互影响的,因而我们可以单独考虑每一个拓扑

[HDU]5094Maze(状态压缩BFS)

状态压缩的题,第一次WA了,怎么改都不对,交了十几遍,之后重新写了一个,1A了 #include<cstdio> #include<queue> #include<cstring> #include<algorithm> using namespace std; const int maxn = 51; const int dir[4][2] = {{0,1},{-1,0},{0,-1},{1,0}}; int n,m,t; int door[maxn][m

hdu 3006(状态压缩)

The Number of set Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1301    Accepted Submission(s): 795 Problem Description Given you n sets.All positive integers in sets are not less than 1 and n

hdu 5135 状态压缩dp

题意是给出最对12条边你     问最大可组成三角形面积是多大 (可有多个三角形)   典型的状态压缩  (最多12条边) 思路: 先暴力枚举所有可能三角形的面积   然后再根据状态压缩来做    最多可组成n/3个三角形  对每个三角形都记录三边或(运算)    和面积    然后判断进行合并  (根据且运算)   就行了 #include<stdio.h> #include<string.h> #include<cmath> #include<iostream

HDU 2553 状态压缩

N皇后问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 23888    Accepted Submission(s): 10639 Problem Description 在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上.你的任务是,对于给定的N,求

hdu 3811 状态压缩

题意就不对说了:  开始想用深搜过  感觉数据水的话应该能过,  哈哈  还是超时了!!! 正确做法应该是状态压缩吧,n小于等于17    2^17-1种状态,每种状态表示对应的数用没用过,如果用状态压缩dp的思路(从小状态跑到大状态)的话就不对了,开始一直没想明白,仔细想想也是,如果按以前的 就会改变dp里面的值,实际上对每一种状态的值是一定的,还有就是为什么要跑结果的对立面,看看测试数据   ,两个要求之间是有重复的,比如1,1和2,2    这样跑起来就不方便. 跑的时候三重for   外

hdu 1074 状态压缩

http://acm.hdu.edu.cn/showproblem.php?pid=1074 我们可以断定状态的终止态一定是n个数全部选完的情况,那么它的前一个状态是什么呢,一定是剔除任一门课程后的n种状态. 例如 dp[全选了]=min{(dp[除了math都做了]+math的超时天数),(dp[除了computer都做了]+computer的超时天数),(dp[除了english都做了]+english的超时天数)}那么接下来的dp状态依然如此. 好了,接下来,我们该如何去思考了,这个题目共

HDU 4856 (状态压缩DP+TSP)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4856 题目大意:有一个迷宫.迷宫里有些隧道,每个隧道有起点和终点,在隧道里不耗时.出隧道就耗时,你的任务是访问完所有隧道且仅一次,求最短耗时. 解题思路: 暑假练习的时候.把英文读了N遍也没理解题意. 其实就是个最后不回到开头的TSP. 首先求BFS求两两隧道之间的最短路,注意BFS的起点是隧道i的终点,BFS的终点是隧道j的起点. 一定要特判一下两个隧道终点和起点是否一样,如果一样话dis=0,