题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1522

很好的思想。考虑从小到大一对一对填数,这样也能对它的大小限制做一些操作了。

因为从小到大,所以只能全填在左边、全填在右边、两边各填一个。记录左边填到了哪个位置,就可知右边填到了哪个位置。转移之前判断一下这样填是否合法即可。

新的不合法的状态只会和现在填的两个位置有关。

注意输入格式!!符号前后有空格!!!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=,M=;
int n,m,x[M],y[M],sgn[M],tx,ty;
ll dp[N][N<<],ans;
char ch[];
bool check(int p0,int p1,int r,int fx)
{
//printf("p0=%d p1=%d r=%d fx=%d\n",p0,p1,r,fx);
for(int i=;i<=m;i++)
if(sgn[i]==&&
( ( (x[i]==p0||x[i]==p1)&&y[i]!=p0&&y[i]!=p1)||
( (y[i]==p0||y[i]==p1)&&x[i]!=p0&&x[i]!=p1) ) )
return ;//以前都合法,不合法仅出现在p0、p1位置上
if(!fx)
{
for(int i=;i<=m;i++)
{
//printf("sgn[%d]=%d\n",i,sgn[i]);
if(sgn[i]==||sgn[i]==)
{
tx=x[i];ty=y[i];
if(sgn[i]==)swap(tx,ty);
//printf("tx=%d ty=%d p0=%d p1=%d r=%d\n",tx,ty,p0,p1,r);
if((ty==p0||ty==p1)&&tx>=p0&&tx<r) return ;
}
if(sgn[i]==||sgn[i]==)
{
tx=x[i];ty=y[i];
if(sgn[i]==)swap(tx,ty);
if((ty==p0||ty==p1)&&tx>p1&&tx<r) return ;
}
}
}
if(fx==)
{
for(int i=;i<=m;i++)
{
if(sgn[i]==||sgn[i]==)
{
tx=x[i];ty=y[i];
if(sgn[i]==)swap(tx,ty);
if((ty==p0||ty==p1)&&tx<=p1&&tx>r) return ;
}
if(sgn[i]==||sgn[i]==)
{
tx=x[i];ty=y[i];
if(sgn[i]==)swap(tx,ty);
if((ty==p0||ty==p1)&&tx<p0&&tx>r) return ;
}
}
}
if(fx==)
{
for(int i=;i<=m;i++)
{
if(sgn[i]==||sgn[i]==)
{
tx=x[i];ty=y[i];
if(sgn[i]==)swap(tx,ty);
if((ty==p0||ty==p1)&&tx>=p0&&tx<=p1) return ;
}
if(sgn[i]==||sgn[i]==)
{
tx=x[i];ty=y[i];
if(sgn[i]==)swap(tx,ty);
if((ty==p0||ty==p1)&&tx>p0&&tx<p1) return ;
}
}
}
return ;
}
int main()
{
scanf("%d%d",&n,&m);ch[]=getchar();
while(ch[]!='\n')ch[]=getchar();
for(int i=,len=,j;i<=m;i++,len=)
{
ch[++len]=getchar();
while(ch[len]!='\n')ch[++len]=getchar();
for(j=;j<len;j++)
{
if(ch[j]>=''&&ch[j]<='')
x[i]=(x[i]<<)+(x[i]<<)+ch[j]-'';
else break;
}
while(ch[j]==' ')j++;
//printf("j=%d chj=(%c)\n",j,ch[j]);
if(ch[j]=='=') sgn[i]=,j++;
else if(ch[j]=='<'&&ch[j+]=='=')sgn[i]=,j+=;
else if(ch[j]=='>'&&ch[j+]=='=')sgn[i]=,j+=;
else if(ch[j]=='<')sgn[i]=,j++;
else if(ch[j]=='>')sgn[i]=,j++;
while(ch[j]==' ')j++;
//printf("j=%d chj=(%c)\n",j,ch[j]);
for(;j<len;j++)
y[i]=(y[i]<<)+(y[i]<<)+ch[j]-'';
//printf("x=%d sgn=%d y=%d\n",x[i],sgn[i],y[i]);
}
dp[][]=;
for(int i=,lm;i<n;i++)
{
lm=(i<<);
for(int j=,r;j<=lm;j++)
{
//if(dp[i][j])printf("dp[%d][%d]=%lld\n",i,j,dp[i][j]);
r=(n<<)-(lm-j)+;
if(check(j+,j+,r,))
dp[i+][j+]+=dp[i][j];
//printf("dp[%d][%d]=%lld(%d,%d)\n",i+1,j+2,dp[i+1][j+2],i,j);
if(check(r-,r-,j,))
dp[i+][j]+=dp[i][j];
//printf("dp[%d][%d]=%lld(%d,%d)\n",i+1,j,dp[i+1][j],i,j);
if(check(j+,r-,,))
dp[i+][j+]+=dp[i][j];
//printf("dp[%d][%d]=%lld(%d,%d)\n",i+1,j+1,dp[i+1][j+1],i,j);
}
}
int lm=(n<<);
for(int j=;j<=lm;j++) ans+=dp[n][j];
printf("%lld\n",ans/);
return ;
}

51 nod 1522 上下序列——序列dp的更多相关文章

  1. 51 nod 1055 最长等差数列(dp)

    1055 最长等差数列 基准时间限制:2 秒 空间限制:262144 KB 分值: 80 难度:5级算法题 N个不同的正整数,找出由这些数组成的最长的等差数列.     例如:1 3 5 6 8 9 ...

  2. 51 nod 1610 路径计数(Moblus+dp)

    1610 路径计数 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题   路径上所有边权的最大公约数定义为一条路径的值. 给定一个有向无环图.T次修改操作,每次修改一 ...

  3. codevs 1962 马棚问题--序列型DP

    1962 马棚问题  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description 每天,小明和他的马外出,然后他们一边跑一边玩耍.当他们结束 ...

  4. 括号序列的dp问题模型

    括号序列的dp问题模型 Codeforces314E ◦给定一个长度为n的仅包含左括号和问号的字符串,将问号变成左括号或 右括号使得该括号序列合法,求方案总数. ◦例如(())与()()都是合法的括号 ...

  5. [BZOJ 3992] [SDOI 2015] 序列统计(DP+原根+NTT)

    [BZOJ 3992] [SDOI 2015] 序列统计(DP+原根+NTT) 题面 小C有一个集合S,里面的元素都是小于质数M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数 ...

  6. 5.13 省选模拟赛 优雅的绽放吧,墨染樱花 多项式 prufer序列 计数 dp

    LINK:优雅的绽放吧,墨染樱花 当时考完只会50分的做法 最近做了某道题受到启发 故会做这道题目了.(末尾附30分 50分 100分code 看到度数容易想到prufer序列 考虑dp统计方案数. ...

  7. At grand 022 GCD序列构造 dp/floyd二进制变换最少费用

    A diverse words指的是每一个字母在单词中出现的次数不超过1的单词 题目要求你求出字典序比当前给定单词大的字典序最小单词 1.如果给定的单词长度小于26 就遍历一次在单词尾部加上字典序最小 ...

  8. 51 nod 1495 中国好区间

    1495 中国好区间 基准时间限制:0.7 秒 空间限制:131072 KB 分值: 80 难度:5级算法题   阿尔法在玩一个游戏,阿尔法给出了一个长度为n的序列,他认为,一段好的区间,它的长度是& ...

  9. 51 nod 1427 文明 (并查集 + 树的直径)

    1427 文明 题目来源: CodeForces 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 160 难度:6级算法题   安德鲁在玩一个叫“文明”的游戏.大妈正在帮助他. 这个游 ...

随机推荐

  1. Fakeapp2.2安装,使用简记--------------转载自iJessie

    原文:https://www.cnblogs.com/iJessie/p/8568377.html 1,硬件和操作系统,支持cuda的Nvidia显卡,8G及以上的内存,Windows10 x64(推 ...

  2. matlab中文显示乱码:控制台上的,编辑器的,图片中的

    问题:matlab脚本与函数文件的中文注释显示乱码. 环境:matlab R2016a.Windows 10 home. 解决方案: step1 检查locale值 matlab命令行键入命令 fea ...

  3. python之脚本参数optparse

    import optparse usage = "myprog[ -f <filename>][-s <xyz>] arg1[,arg2..]" opter ...

  4. eclipse-jee版配置tomcat

    Eclipse作为一款优秀的java开发开源IDE,集成了许多优秀的开发控件.下来我就如何安装eclipse及插件进行说明: 一.JDK安装   JDK是作为整个java的核心,包括运行环境,编译工具 ...

  5. php开启pathinfo 模式

    pathinfo 模式 需要 php.ini 开启下面这个参数 cgi.fix_pathinfo=1 path_info模式:http://www.xxx.com/index.php/模块/方法   ...

  6. golang截取字符串

    对于字符串操作,截取字符串是一个常用的, 而当你需要截取字符串中的一部分时,可以使用像截取数组某部分那样来操作,示例代码如下: package main import "fmt" ...

  7. mnesia的脏写和事物写的测试

    在之前的文章中,测试了脏读和事物读之间性能差别,下面测试下脏写和事物写之间的性能差别: 代码如下: -module(mnesia_text). -compile(export_all). -recor ...

  8. 利用树的先序和后序遍历打印 os 中的目录树

    [0]README 0.1)本代码均为原创,旨在将树的遍历应用一下下以加深印象而已:(回答了学习树的遍历到底有什么用的问题?)你对比下linux 中的文件树 和我的打印结果就明理了: 0.2)我们采用 ...

  9. Linux - 命令行 管道(Pipelines) 具体解释

    命令行 管道(Pipelines) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/24249529 管道操作符" ...

  10. Jquery获取iframe中的元素

    iframe与父页面之间相互获取元素的方法: 1.从父页面中获取iframe页面中的元素: 用法: $(window.frames["iframe_include_adverse" ...