题目链接:CSAPC08台湾邀请赛_T1_skyline

题目描述

一座山的山稜线由许多片段的45度斜坡构成,每一个片段不是上坡就是下坡。

/ *

/​ * * /

​/ * /\ //

​/ // /

在我们眼前的所见的任何宽度为n个单位的山稜形状,可以轻松地观察到所有山顶的位置。

请问有多少种山稜线的形状,使得所有山顶的位置由左而右非递减呢?

所有的山稜线都必须完整,也就是说左右两端都必须是高度为0的山脚,而且不能有任何山谷的位置隐没在地平线底下。

输入输出格式

输入格式

输入仅包含一个数字n,n一定会是偶数,因为会有相同片段数量的上坡以及下坡。

输出格式

请输出山顶位置由左而右非递减的山稜线形状总数。

由于答案可能很大,你只要输出以十进位表示时,它的最后9位数即可。

样例

INPUT

6

OUTPUT

4

HINT

佔总分20%的测试数据中 n<=60

佔总分40%的测试数据中 n<=200

佔总分100%的测试数据中 n<=3000

SOLUTION

这题考场上耗了我大半的时间还没搞出来qwq。

首先,根据题意分析,很容易就能看出这是个区间dp。

区间dp怎么传递呢?看到题目要求:求宽度为\(n\),山顶高度非降的方案和。所以我们可以开一个二维数组\(dp[i][j]\)记录答案:第一维\(i\)用来记录限定条件:“宽度”;第二维\(j\)来记录限定条件:这些山峰的最高高度\(j\),以便转移。

但是啊,我们的\(dp\)数组只能记录最高高度为\(j\)的情况,那如果我要拓宽宽度的话,肯定是不能再把所有的最高高度的情况又重新枚举累加的,所以考虑用一个前缀和数组\(sum[i][j]\)来记录宽度为\(i\),最高高度限定为\(j\)(可以小于\(j\))的所有情况,可以说\(sum\)数组就是把宽度为\(i\)的所有合法情况记录了下来。

接下来就是转移了。

首先我们有两大种情况:

Ⅰ.我们的\(dp[i][j]\)的情况可以直接由\(dp[i-1][j-1]\)的情况得到;

这就相当于可以想象把\(dp[i-1][j-1]\)中包含的山的情况整体往上拱了一层。如下图:



Ⅱ.我们也可以通过在\(sum[i-2][j]\)的基础上加上一座最小的山。如下图:

因为\(sum[i-2][j]\)加上一座单位高度的小山已经把类似于最低山的高度大于单位长度的所有情况考虑了进来,而我们的情况Ⅰ就是对应着这种“最低山的高度大于单位长度”的所有情况。

所以任何情况已经可以用以上两种情况相互叠加着表示,可以保证的是这么算目前已经没有遗漏了。

但其实还会存在一个小问题。

在整体宽度为\(i+j\)时,假设我们的右边有一座高度为\(j\)的山峰,那么显然地,这座山峰的宽度为\(2j\),所以去掉右边的山峰后,我们左边部分的山峰宽度为\(i-j\),那么我们的\(sum[i-2j][j]\)就可以表示当前说的这种情况的所有方案,此时是合法的。

不过我们若将左边部分的宽度减少一个单位匀给右边部分,右边部分一定不能在保持只有一座山峰的情况下保证最高高度为\(j\),所以不合法。

但是可能会有点想不通的是:为什么右边就一定只能有一座山峰呢?

其实,注意一下我们的转移方程,我们的\(sum[i-2][j]\)是通过和一个单位高度的山峰组合在一起作为答案加进我们的\(dp\)数组里去的,然后当我们的单位高度小山峰被垫高到了高度\(j\)时,与它同组搭配的\(sum\)数组的组合情况就必须考虑一下其合法性了,因为这种非法组合也本来就不能算在答案里。于是考虑删除。

代码就在下面,这篇题解其实更多就是对下面的代码的解释因为这个标程一点注释都没有啊。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
const int N=3010;
const int P=1000000000;
int n,dp[N][N],sum[N][N];
int main(){
int i,j;
memset(dp,0,sizeof(dp));memset(sum,0,sizeof(sum));
dp[1][1]=1;sum[1][1]=1;
for (i=2;i<=3000;++i){
for (j=1;j<i;++j){
if ((i+j)%2==0){
dp[i][j]=(dp[i-1][j-1]+sum[i-2][j])%P;
if (i-j-j>0) {dp[i][j]=(dp[i][j]-sum[i-j-j-1][j]+P)%P;}
}
sum[i][j]=(sum[i-1][j]+dp[i][j])%P;
}
dp[i][i]=1;sum[i][i]=1;
}
while (scanf("%d",&n)!=EOF){
int ans=0;
for (i=1;i<=n/2;++i) {ans=(ans+dp[n-i][i])%P;}
printf("%d\n",ans);
}
return 0;
}

CSAPC08台湾邀请赛_T1_skyline的更多相关文章

  1. 1250 Super Fast Fourier Transform(湘潭邀请赛 暴力 思维)

    湘潭邀请赛的一题,名字叫"超级FFT"最终暴力就行,还是思维不够灵活,要吸取教训. 由于每组数据总量只有1e5这个级别,和不超过1e6,故先预处理再暴力即可. #include&l ...

  2. 每周一书-《鸟哥的Linux私房菜基础学习篇(第四版)》台湾原版,你想要吗?

     首先说明,本周活动有效时间为2016年10月19日到2016年10月31日.   目在介绍这本书之前,首先要感谢QQ号为:1084830483(路在远方),来自哈尔滨工程大学的同学赠送给玄魂工作室的 ...

  3. 2014嘉杰信息杯ACM/ICPC湖南程序设计邀请赛暨第六届湘潭市程序设计竞赛

    比赛链接: http://202.197.224.59/OnlineJudge2/index.php/Contest/problems/contest_id/36 题目来源: 2014嘉杰信息杯ACM ...

  4. 台湾辅仁大学的python教程笔记

    散记,因为主讲老师讲得也很乱..说课后的自习才是最重要的- 1.就这样,笔记看下.. 2. Modules 模组 很多模组放在一起就是一个packages 一个packages 一定有有__init_ ...

  5. java 实现从15位~18位的身份证号码转换,校验中国大陆公民身份证、香港居民身份证、澳门身份证和台湾身份证。

    package xidian.sl.netcredit.util; /** * Copyright (C) 2009-2010 Yichuan, Fuchun All rights reserved. ...

  6. 湘潭邀请赛 Hamiltonian Path

    湘潭邀请赛的C题,哈密顿路径,边为有向且给定的所有边起点小于终点,怎么感觉是脑筋急转弯? 以后一定要牢记思维活跃一点,把复杂的事情尽量简单化而不是简单的事情复杂化. #include<cstdi ...

  7. 2014 ACM/ICPC 北京邀请赛 部分 题解

    题目链接:http://acm.bnu.edu.cn/bnuoj/problem.php?search=2014+ACM-ICPC+Beijing+Invitational+Programming+C ...

  8. zw版【转发·台湾nvp系列Delphi例程】HALCON DirectShow (Delphi Prism)

    zw版[转发·台湾nvp系列Delphi例程]HALCON DirectShow (Delphi Prism) namespace DirectShow_Prism;interfaceuses Sys ...

  9. zw版【转发·台湾nvp系列Delphi例程】HALCON HImage与Bitmap格式转换

    zw版[转发·台湾nvp系列Delphi例程]HALCON HImage与Bitmap格式转换 (Delphi Prism)namespace HImage_Bitmap_Prism;interfac ...

随机推荐

  1. Kattis dragonball1 Dragon Ball I(最短路)

    There is a legendary tale about Dragon Balls on Planet X: if one collects seven Dragon Balls, the Dr ...

  2. PAT Advanced 1029 Median (25) [two pointers]

    题目 Given an increasing sequence S of N integers, the median is the number at the middle position. Fo ...

  3. vscode template中设置不换行

    { "workbench.colorTheme": "Dark-Dracula", "workbench.iconTheme": " ...

  4. 拉格朗日插值Python代码实现

    1. 数学原理 对某个多项式函数有已知的k+1个点,假设任意两个不同的都互不相同,那么应用拉格朗日插值公式所得到的拉格朗日插值多项式为: 其中每个lj(x)为拉格朗日基本多项式(或称插值基函数),其表 ...

  5. quartz2.2.1bug

    quartz2.1.5 调用 scheduler.start()方法时报这样一个异常: 严重: An error occurred while scanning for the next trigge ...

  6. Graph & Trees3 - 二分图

    \[二分图略解\] \[By\;TYQ\] 二分图定义: \(f(i,L) = [a \in L\;\text{&}\;\forall b \in a.to \;\text{,}\; b \n ...

  7. Django_HTML

    一.web开发之HTML 1.1 HTML相关基础 快速生成html的模版方法: 在visual code的新建html文件中输入:!然后tab回车就会出现HTML的模版 双标签: <p> ...

  8. 记录一次追踪@AutoWired的过程

    目录 记录一次追踪@AutoWired的过程 前言 疑惑:依赖究竟是怎么自动注入的 AutoWiredAnnotationBeanPostProcessor中探究 自动注入debug流程追踪 dete ...

  9. 吴裕雄--天生自然TensorFlow高层封装:Keras-返回值

    # 1. 数据预处理. import keras from keras.models import Model from keras.datasets import mnist from keras. ...

  10. 14 微服务电商【黑马乐优商城】:day04-ES6语法入门

    day01-springboot(理论篇) :day01-springboot(实践篇) day02-springcloud(理论篇一)  :day02-springcloud(理论篇二)  :day ...