51Nod 1522 上下序列 —— 区间DP
题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1522
区间DP,从大往小加;
新加入一种数有3种加法:全加左边,全加右边,一左一右;
然后判断一下加完是否满足那些条件即可;
但判断这个条件还挺复杂,一不小心就写丑了错了...
冗余错误写法:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int n,m,c[][];
ll f[][][];
char ch[];
bool ck(int a,int b,int fl)
{
if(fl==)
{
for(int i=,x,y;i<=m;i++)
{
x=c[i][]; y=c[i][];
if((x==a&&y==b)||(x==b&&y==a)&&c[i][]!=)return ;
if((x==a||x==b)&&y>b&&(c[i][]!=&&c[i][]!=))return ;
if((y==a||y==b)&&x>b&&(c[i][]!=&&c[i][]!=))return ;
}
return ;
}
if(fl==)
{
for(int i=,x,y;i<=m;i++)
{
x=c[i][]; y=c[i][];
if((x==a&&y==b)||(x==b&&y==a)&&c[i][]!=)return ;
if((x==a||x==b)&&y<a&&(c[i][]!=&&c[i][]!=))return ;
if((y==a||y==b)&&x<a&&(c[i][]!=&&c[i][]!=))return ;
}
return ;
}
if(fl==)
{
for(int i=,x,y;i<=m;i++)
{
x=c[i][]; y=c[i][];
if((x==a&&y==b)||(x==b&&y==a)&&c[i][]!=)return ;
if((x==a||x==b)&&(y>a&&y<b)&&(c[i][]!=&&c[i][]!=))return ;
if((y==a||y==b)&&(x>a&&x<b)&&(c[i][]!=&&c[i][]!=))return ;
}
return ;
}
if(fl==)
{
for(int i=,x=c[i][],y=c[i][];i<=m;i++,x=c[i][],y=c[i][])
if((x==a&&y==b)||(x==b&&y==a)&&(c[i][]==||c[i][]==))return ;
return ;
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
scanf("%d %s %d",&c[i][],&ch,&c[i][]);
if(ch[]=='=')c[i][]=;
else if(ch[]=='<'&&ch[]=='=')c[i][]=;
else if(ch[]=='>'&&ch[]=='=')c[i][]=;
else if(ch[]=='<')c[i][]=;
else if(ch[]=='>')c[i][]=;
}
for(int i=;i<*n;i++)if(ck(i,i+,))f[n][i][i+]=;
for(int i=n-;i;i--)
for(int l=;l<=*n;l++)
for(int r=l+;r<=*n;r++)
if(f[i+][l][r])
{
// printf("i=%d l=%d r=%d\n",i,l,r);
int x,y;
if(l>)
{
x=l-,y=l-;
if(ck(x,y,))f[i][x][r]+=f[i+][l][r];
// printf("f[%d][%d][%d]=%d\n",i,x,r,f[i][x][r]);
}
if(r+<=*n)
{
x=r+,y=r+;
if(ck(x,y,))f[i][l][y]+=f[i+][l][r];
// printf("f[%d][%d][%d]=%d\n",i,l,y,f[i][l][y]);
}
if(l>&&r+<=*n)
{
x=l-; y=r+;
if(ck(x,y,))f[i][x][y]+=f[i+][l][r];
// printf("f[%d][%d][%d]=%d\n",i,x,y,f[i][x][y]);
}
}
printf("%lld\n",f[][][n<<]);
return ;
}
囧
于是参考了一下TJ...
调了一小时只因把 x==b 写成 y==b ?!而且还一直没仔细看...
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int n,m,c[][];
ll f[][];
char ch[];
bool ck0(int a,int b)
{
for(int i=,x=c[i][],y=c[i][];i<=m;i++,x=c[i][],y=c[i][])
if(((x==a&&y==b)||(x==b&&y==a))&&(c[i][]==||c[i][]==))return ;
return ;
}
bool ck(int l,int r,int a,int b)
{
for(int i=;i<=m;i++)
{
int x=c[i][],y=c[i][],cc=c[i][];
bool ix=(x==a||x==b),iy=(y==a||y==b);
bool kx=(x>=l&&x<=r),ky=(y>=l&&y<=r);
if(cc==&&((ix!=iy)||(kx!=ky)))return ;//=
if(cc==&&(!ky&&(ix||kx)))return ;//<
if(cc==&&(!kx&&(iy||ky)))return ;//>
if(cc==&&((ix&&!iy&&!ky)||(kx&&!ky)))return ;//<=
if(cc==&&((iy&&!ix&&!kx)||(ky&&!kx)))return ;//>=
}
return ;
}
int main()
{
scanf("%d%d",&n,&m);
bool flag=; int cnt=;
for(int i=,x,y,cc;i<=m;i++)
{
scanf("%d %s %d",&x,&ch,&y);
if(ch[]=='=')cc=;
else if(ch[]=='<'&&ch[]=='=')cc=;
else if(ch[]=='>'&&ch[]=='=')cc=;
else if(ch[]=='<')cc=;
else if(ch[]=='>')cc=;
if(x==y)
{
if(cc==||cc==)flag=;
continue;//!
}
c[++cnt][]=x; c[cnt][]=y; c[cnt][]=cc;
}
if(flag){printf("0\n"); return ;}
m=cnt;
for(int i=;i<*n;i++)if(ck0(i,i+))f[i][i+]=;
for(int l=;l<=*n;l+=)
for(int i=;i<=*n-l+;i++)
{
int j=i+l-;
if(ck(i+,j,i,i+))f[i][j]+=f[i+][j];
if(ck(i,j-,j-,j))f[i][j]+=f[i][j-];
if(ck(i+,j-,i,j))f[i][j]+=f[i+][j-];
}
printf("%lld\n",f[][*n]);
return ;
}
51Nod 1522 上下序列 —— 区间DP的更多相关文章
- $51nod\ 1522$ 上下序列 $dp$
正解:$dp$ 解题报告: 传送门$QwQ$ 一年过去了$gql$还是不咋会这题,,,好菜昂我的$NOIp$必将惨败了$kk$ 考虑从大到小枚举两个相同的数填哪儿,根据那个限制,十分显然的是这两个数必 ...
- 51nod 1522 上下序列
题目描述 现在有1到n的整数,每一种有两个.要求把他们排在一排,排成一个2*n长度的序列,排列的要求是从左到右看,先是不降,然后是不升. 特别的,也可以只由不降序列,或者不升序列构成. 例如,下面这些 ...
- 编程之美2015资格赛 题目2 : 回文字符序列 [ 区间dp ]
传送门 题目2 : 回文字符序列 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定字符串,求它的回文子序列个数.回文子序列反转字符顺序后仍然与原序列相同.例如字符串ab ...
- 51nod 1021 石子归并 - 区间dp(经典)
题目地址:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1021 经典区间dp,dp[i][j] 表示将从 i 到 j 堆 ...
- TZOJ 3295 括号序列(区间DP)
描述 给定一串字符串,只由 “[”.“]” .“(”.“)”四个字符构成.现在让你尽量少的添加括号,得到一个规则的序列. 例如:“()”.“[]”.“(())”.“([])”.“()[]”.“()[( ...
- 51nod 1021 石子归并 区间DP
1021 石子归并 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 取消关注 N堆石子摆成一条线.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆 ...
- 51Nod 1021 石子归并(区间dp经典入门)
题意: N堆石子摆成一条线.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价.计算将N堆石子合并成一堆的最小代价. n<=100 思 ...
- 【区间DP】codevs3657 括号序列题解
题目描述 Description 我们用以下规则定义一个合法的括号序列: (1)空序列是合法的 (2)假如S是一个合法的序列,则 (S) 和[S]都是合法的 (3)假如A 和 B 都是合法的,那么AB ...
- [BZOJ 4350]括号序列再战猪猪侠 题解(区间DP)
[BZOJ 4350]括号序列再战猪猪侠 Description 括号序列与猪猪侠又大战了起来. 众所周知,括号序列是一个只有(和)组成的序列,我们称一个括号 序列S合法,当且仅当: 1.( )是一个 ...
随机推荐
- Python:webshell 跳板机审计服务器
1.修改paramiko源码包实现 https://github.com/paramiko/paramiko/tree/1.10.1 下载源码包 unzip paramiko-1.10.1.zip p ...
- 第二周习题F
Starting with x and repeatedly multiplying by x, we can compute x31 with thirty multiplications: x2 ...
- JQuery Easy UI 简介
[什么是JQuery Easy UI?] jQuery EasyUI 是一组基于 jQuery 的 UI 插件集合,而 jQuery EasyUI 的目标就是帮助Web 开发者更轻松的打造出功能丰富并 ...
- 添物不花钱学JavaEE(基础篇) --HTML
HTML是什么? HTML – Hyper Text Markup Language HTML官方网址 http://www.w3.org/TR/2014/REC-html5-20141028/ 其实 ...
- CSUOJ 1542 线段树解决括号反向问题
题目大意: 根据初始给定的合法的小括号排序,每次进行一个操作,将第a位的括号反向,找到一个尽可能靠前的括号反向后是整个括号排列合法 数据量十分大,不断进行查询,要用线段树进行logn的复杂度的查询 首 ...
- Reactor Cooling(无源汇有上下界网络流)
194. Reactor Cooling time limit per test: 0.5 sec. memory limit per test: 65536 KB input: standard o ...
- Spring Data JPA 之 一对一,一对多,多对多 关系映射
一.@OneToOne关系映射 JPA使用@OneToOne来标注一对一的关系. 实体 People :用户. 实体 Address:家庭住址. People 和 Address 是一对一的关系. 这 ...
- 2018/3/14 Hadoop学习笔记(一)
首先,什么是Hadoop?为什么它是现在大数据处理最热门的框架呢?(正确来说,现在Hadoop是一个生态圈) Hadoop是apache下一套开源的服务框架,它主要的作用就是利用服务器集群,来对海量数 ...
- Linux下汇编语言学习笔记22 ---
这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...
- Linux下汇编语言学习笔记17 ---
这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...