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.( )是一个 ...
随机推荐
- 树莓派 -- oled 续(1) wiringPi
在上文中,分析了wiringPi 的oled demo是使用devfs来控制spi master和spi slave通讯. https://blog.csdn.net/feiwatson/articl ...
- Jquery 动态添加元素后,获取不到元素对象情况
- ORM之单表增删改查
ORM之单表增删改查 在函数前,先导入要操作的数据库表模块,model from model所在的路径文件夹 import model 在views文件中,加的路径: #就一个app01功能的文件 ...
- Python接口测试之对MySQL的操作(六)
本文章主要来说python对mysql数据库的基本操作,当然,前提是已经搭建了python环境和搭建了Mysql 数据库的环境,python操作mysql数据库提供了MySQLdb库,下载的地址为: ...
- 洛谷 P2285 BZOJ 1207 [HNOI2004]打鼹鼠
题目描述 鼹鼠是一种很喜欢挖洞的动物,但每过一定的时间,它还是喜欢把头探出到地面上来透透气的.根据这个特点阿牛编写了一个打鼹鼠的游戏:在一个n*n的网格中,在某些时刻鼹鼠会在某一个网格探出头来透透气. ...
- hdu 4871 树的分治+最短路记录路径
/* 题意:给你一些节点和一些边,求最短路径树上是k个节点的最长的路径数. 解:1.求出最短路径树--spfa加记录 2.树上进行操作--树的分治,分别处理子树进行补集等运算 */ #include& ...
- hihocoder #1034 : 毁灭者问题 平衡树(set)+线段树
#1034 : 毁灭者问题 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在 Warcraft III 之冰封王座中,毁灭者是不死族打三本后期时的一个魔法飞行单位. 毁 ...
- bzoj 2588 Spoj 10628. Count on a tree (可持久化线段树)
Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 7669 Solved: 1894[Submi ...
- Jquery EasyUI动态生成Tab
function addTab(title, url) { if ($('#tt').tabs('exists', title)) { $('#tt').tabs('select', title); ...
- __asm
来源:http://msdn.microsoft.com/zh-cn/library/45yd4tzz.aspx Microsoft 专用 __asm 关键字调用一个内联汇编,并且可以显示,每当 c. ...