题目: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=40,M=105;
int n,m,x[M],y[M],sgn[M],tx,ty;
ll dp[N][N<<1],ans;
char ch[20];
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=1;i<=m;i++)if(sgn[i]==0&&( ( (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 0;//以前都合法,不合法仅出现在p0、p1位置上if(!fx){for(int i=1;i<=m;i++){//printf("sgn[%d]=%d\n",i,sgn[i]);if(sgn[i]==1||sgn[i]==2){tx=x[i];ty=y[i];if(sgn[i]==2)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 0;}if(sgn[i]==3||sgn[i]==4){tx=x[i];ty=y[i];if(sgn[i]==4)swap(tx,ty);if((ty==p0||ty==p1)&&tx>p1&&tx<r) return 0;}}}if(fx==1){for(int i=1;i<=m;i++){if(sgn[i]==1||sgn[i]==2){tx=x[i];ty=y[i];if(sgn[i]==2)swap(tx,ty);if((ty==p0||ty==p1)&&tx<=p1&&tx>r) return 0;}if(sgn[i]==3||sgn[i]==4){tx=x[i];ty=y[i];if(sgn[i]==4)swap(tx,ty);if((ty==p0||ty==p1)&&tx<p0&&tx>r) return 0;}}}if(fx==2){for(int i=1;i<=m;i++){if(sgn[i]==1||sgn[i]==2){tx=x[i];ty=y[i];if(sgn[i]==2)swap(tx,ty);if((ty==p0||ty==p1)&&tx>=p0&&tx<=p1) return 0;}if(sgn[i]==3||sgn[i]==4){tx=x[i];ty=y[i];if(sgn[i]==4)swap(tx,ty);if((ty==p0||ty==p1)&&tx>p0&&tx<p1) return 0;}}}return 1;
}
int main()
{scanf("%d%d",&n,&m);ch[0]=getchar();while(ch[0]!='\n')ch[0]=getchar();for(int i=1,len=0,j;i<=m;i++,len=0){ch[++len]=getchar();while(ch[len]!='\n')ch[++len]=getchar();for(j=1;j<len;j++){if(ch[j]>='0'&&ch[j]<='9')x[i]=(x[i]<<3)+(x[i]<<1)+ch[j]-'0';else break;}while(ch[j]==' ')j++;//printf("j=%d chj=(%c)\n",j,ch[j]);if(ch[j]=='=') sgn[i]=0,j++;else if(ch[j]=='<'&&ch[j+1]=='=')sgn[i]=3,j+=2;else if(ch[j]=='>'&&ch[j+1]=='=')sgn[i]=4,j+=2;else if(ch[j]=='<')sgn[i]=1,j++;else if(ch[j]=='>')sgn[i]=2,j++;while(ch[j]==' ')j++;//printf("j=%d chj=(%c)\n",j,ch[j]);for(;j<len;j++)y[i]=(y[i]<<3)+(y[i]<<1)+ch[j]-'0';//printf("x=%d sgn=%d y=%d\n",x[i],sgn[i],y[i]);
    }dp[0][0]=1;for(int i=0,lm;i<n;i++){lm=(i<<1);for(int j=0,r;j<=lm;j++){//if(dp[i][j])printf("dp[%d][%d]=%lld\n",i,j,dp[i][j]);r=(n<<1)-(lm-j)+1;if(check(j+1,j+2,r,0))dp[i+1][j+2]+=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-2,r-1,j,1))dp[i+1][j]+=dp[i][j];//printf("dp[%d][%d]=%lld(%d,%d)\n",i+1,j,dp[i+1][j],i,j);if(check(j+1,r-1,0,2))dp[i+1][j+1]+=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<<1);for(int j=0;j<=lm;j++) ans+=dp[n][j];printf("%lld\n",ans/3);return 0;
}

转载于:https://www.cnblogs.com/Narh/p/9672719.html

51 nod 1522 上下序列——序列dp相关推荐

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

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

  2. 51 nod 1405 树的距离之和

    1405 树的距离之和 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 给定一棵无根树,假设它有n个节点,节点编号从1到n, 求任意两点之间的距离(最短路径)之和. ...

  3. 51 nod 1439 互质对(Moblus容斥)

    1439 互质对 题目来源: CodeForces 基准时间限制:2 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 有n个数字,a[1],a[2],-,a[n].有一个集合,刚开 ...

  4. [STL乱搞]51 Nod——1573 美丽的集合

    [STL乱搞]51 Nod--1573 美丽的集合 题目梗概 在多重集之中,同一个元素可以出现多次. 我们现在有n个多重集合,第i个集合最开始都有一个元素ai(1≤i≤n). 定义多重集合的价值为子集 ...

  5. 3.17√ 识别次读入的一个以@为结束符的字符序列是否为形如”序列1序列2“模式的字符序列 ,序列12均没有,且序列2为序列1的逆序列

    #include <stdio.h> #include <stdlib.h> #define maxsize 100 #define false -1 #define true ...

  6. 51Nod 1522 上下序列 —— 区间DP

    题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1522 区间DP,从大往小加: 新加入一种数有3种加法:全加左边,全 ...

  7. 编程之美2015资格赛 题目2 : 回文字符序列 [ 区间dp ]

    传送门 题目2 : 回文字符序列 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定字符串,求它的回文子序列个数.回文子序列反转字符顺序后仍然与原序列相同.例如字符串ab ...

  8. FJUT Home_W的拆分序列(DP)题解

    Problem Description Home 现在给你一个序列要求你将这个序列拆成恰好两个子序列.且使得两个子序列的抖动系数之和最大. 对于一个序列c1,c2,c3,--cm. 其抖动系数=|c1 ...

  9. 51 nod 1049 最大子段和 (简单dp)

    1049 最大子段和  基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 N个整数组成的序列a[1],a[2],a[3],-,a[n],求该序列如a[i]+a[i+1]+- ...

最新文章

  1. python joblib库 并行化 缓存
  2. VS2010水晶报表的添加与使用
  3. Vivado中debug用法
  4. mysql性能测试工具msyqlslap_mysqlslap工具测试mysql DB的性能
  5. 命令 启动顺序_笔记一: 启动选项与系统变量
  6. mplab x ide 中文使用手册_SCI必备利器:翻译又快又准,强推这款超牛X的神器!...
  7. 铁乐学python_Day42_锁和队列
  8. 使用 Docker 部署 Node 服务
  9. 清空临时表oracle,【Oracle相关】Oracle中如何清空临时表空间
  10. 字段与属性 c# 1613532992
  11. 页面JS实现按钮点击增加输入框
  12. 51nod1057-大数阶乘
  13. 条件判断结构掷骰子游戏
  14. 解决数据库日志文件过大的问题
  15. IT中文技术站十大网站收藏
  16. 动态表情与超链接制作
  17. 怎么用matlab画一个笑脸,MATLAB笑脸识别
  18. 故宫景点功课24:宁寿宫区6
  19. 苏宁0元撸货福利来了!只限新人!老用户放弃吧!便宜只能占一次
  20. 两条命令彻底修复动态链接库

热门文章

  1. 在linux上安装mysql5.6,在linux(Centos 7以上版本亲测)上安装mysql5.6
  2. 使用注解版AOP解决事务问题
  3. 6 日期字符串转日期_Java日期时间API系列6-----Jdk8中java.time包中的新的日期时间API类...
  4. 小程序搜索框_微信小程序搜索及优化相关知识科普
  5. 百分比单位始终根据父元素相应值来计算_CSS Viewport 单位,很多人还不知道使用它来快速布局!...
  6. linux的ctrl alt f6的作用,Linux(Centous6.4)操作系统中,快捷键Alt+Ctrl+F10是什么作用?...
  7. 考研计算机专业课复习,考研中计算机专业课的复习考试.pdf
  8. http协议下需要服务器推送吗,HTTP/2.0 服务器推送实现
  9. xp定时关机软件_好用又免费的电脑定时工具,不用得后悔
  10. Invalid Gradle JDK configuration found_带你了解Gradle编译速度是如何提升70%的