●观光(17.12.02多校联测题目)
题目:
题解:
DP,方案数统计,(神奇)。
题意不再赘述。
但不得不说,做这种dp真的好难受啊。
我们做如下考虑:
首先,起点只有出度,终点只有入度,其它点的出入度均为 1(这个结论好像没啥明显的用处哈)。
如果把 K位置作为终点,那么序列被分为了两段 :[1,K-1] 和 [k+1,N]
那么如何把左右两边"有机地"和终点结合起来呢?
假设,
在左边按照某种方式,用到所有点,连接出了 X 条终点方向指向 K(即指向右边)的链。
在右边按照某种方式,用到所有点,连接出了 Y 条终点方向指向 K(即指向左边)的链。
然后按照一条左边的链,一条右边的链的方式(即交替),最后连上终点 K的方案数为
= X! * Y!
另外,要想能够交替成功,X和 Y的差值不能超过 1。
所以由上面的这个东西得到启发,我们只需要维护出
L[K-1][j] 表示 用到[1,K-1]的区间里的所有点,连接出 j条终点方向指向 K(即指向右边)的链 的方案数。
R[K+1][j] 表示 用到[K+1,N]的区间里的所有点,连接出 j条终点方向指向 K(即指向左边)的链 的方案数。
那么 就可以得出 K为终点时的方案数了。
ans[K]=sigma { L[K-1][j]*R[K+1][j+1] * j! * (j+1)!
+L[K-1][j+1]*R[K+1][j] * (j+1)! * j!
+2*L[K-1][j]*R[K+1][j] * j! *j! } (0<=j<=N)
接下来便是要 DP求出 L[i][j],R[i][j]数组。
以左边为例,先枚举 i(代表用到 [1,i]里的所有点),再枚举 j(表示连接出 j条链)
如果 S[i]=='<',那么有如下转移:
L[i][j]+=(j+1)*j*L[i-1][j+1] 用'<'合并两条链(把'<'放在新形成的链中间)
L[i][j]+=L[i][j]+j*L[i-1][j] 把'<'接在已有的链首
如果 S[i]=='>',那么。。。
L[i][j]+=L[i-1][j-1] 由'>'产生新的链尾(即产生一条新的链)
L[i][j]+=j*L[i-1][j] 把'>'接在已有的链尾
右边 R的处理大同小异,反着来就好了。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXN 1005
#define _ %mod
using namespace std;
const int mod=1000000007;
char S[MAXN];
int L[MAXN][MAXN],R[MAXN][MAXN],fac[MAXN];
int N;
int main()
{scanf("%d",&N); scanf("%s",S+1);if(N==1) {printf("1"); return 0;} fac[0]=1; for(int i=1;i<=N;i++) fac[i]=1ll*i*fac[i-1]_;L[0][0]=1; R[N+1][0]=1;for(int i=1;i<=N;i++)//处理左侧 for(int j=1;j<=N;j++){if(S[i]=='<') L[i][j]=(1ll*L[i][j]+1ll*(j+1)*j*L[i-1][j+1])_,//用'<'合并两条链(把'<'放在链中间)L[i][j]=(1ll*L[i][j]+1ll*j*L[i-1][j])_;//把'<'接在链首elseL[i][j]=(1ll*L[i][j]+1ll*L[i-1][j-1])_,//由'>'产生新的链尾L[i][j]=(1ll*L[i][j]+1ll*j*L[i-1][j])_;//把'>'接在链尾 }for(int i=N;i>=1;i--)//处理右侧 for(int j=1;j<=N;j++){if(S[i]=='>')R[i][j]=(1ll*R[i][j]+1ll*(j+1)*j*R[i+1][j+1])_,//用'>'合并两条链(把'<'放在链中间)R[i][j]=(1ll*R[i][j]+1ll*j*R[i+1][j])_;//把'>'接在链首elseR[i][j]=(1ll*R[i][j]+1ll*R[i+1][j-1])_,//由'<'产生新的链尾R[i][j]=(1ll*R[i][j]+1ll*j*R[i+1][j])_;//把'<'接在链尾}for(int k=1,ans;k<=N;k++){//计算以 K为终点时的方案数 ans=0;for(int j=0;j<=N;j++)ans=(1ll*ans+1ll*L[k-1][j]_*fac[j]_*R[k+1][j+1]_*fac[j+1]_)_,ans=(1ll*ans+1ll*L[k-1][j+1]_*fac[j+1]_*R[k+1][j]_*fac[j]_)_,ans=(1ll*ans+2ll*L[k-1][j]_*fac[j]_*R[k+1][j]_*fac[j]_)_;printf("%d\n",ans);}return 0;
}
转载于:https://www.cnblogs.com/zj75211/p/7954465.html
●观光(17.12.02多校联测题目)相关推荐
- 【跃迁之路】【658天】程序员高效学习方法论探索系列(实验阶段415-2018.12.02)...
@(收集箱(每日一记,每周六整理))专栏 实验说明 从2017.10.6起,开启这个系列,目标只有一个:探索新的学习方法,实现跃迁式成长 实验期2年(2017.10.06 - 2019.10.06) ...
- LoadRunner 12.02 安装教程及中文语言包安装
注意事项: 安装前,把所有的杀毒软件和防火墙关闭. 若以前安装过LoadRunner,则将其卸载. 安装路径不要带中文字符. LoadRunner 12已经不再支持xp系统,仅支持win7和win8系 ...
- 程序员面试金典——17.12整数对查找
程序员面试金典--17.12整数对查找 Solution1:针对重复数字的情况题目未做明确说明,虽然此题仍能AC,但有的重复数字用了1次,有的用了超过1次,要求不清晰.重点是这种前后双指针的方法要会! ...
- 信息学奥赛一本通 1398:短信计费 | OpenJudge NOI 1.12 02:短信计费
[题目链接] ybt 1398:短信计费 OpenJudge NOI 1.12 02:短信计费 [题目考点] 1. 函数 2. <cmath>中的取整函数 向上取整 : double ce ...
- Docker 17.12.0 发布
为什么80%的码农都做不了架构师?>>> 今天早晨6点,Docker发布了17.12版本,这应该是17年的最后一次更新了. 看了下Release Notes),重点是修复了do ...
- HP LoadRunner 12.02 Tutorial T7177-88037教程独家中文版
LoadRunner 12.02教程独家中文版 Tylan独家呕血翻译 转载请注明出自"天外归云"的博客园 Welcome to the LoadRunner Tutorial L ...
- 面试题 17.12. BiNode
面试题 17.12. BiNode Ideas 可以看到示例的输出是有序的,对于BST来说,middle order traversal得到的就是一个有序列表,所以要拿它做文章. Code Pytho ...
- Leetcode每日一题:面试题17.12 binode
面试题 17.12. BiNode 二叉树的中序遍历是弱项,需要额外练习,特别是二叉搜索树的中序遍历,利用它是递增数列的性质: 通过一个pre来不断地修改节点指向,有左节点优先左节点,没有则右节点,p ...
- http://www.blogjava.net/heyang/archive/2010/12/02/
2019独角兽企业重金招聘Python工程师标准>>> http://www.blogjava.net/heyang/archive/2010/12/02/339589.html 使 ...
最新文章
- 【Vegas2007】11月23日-螃蟹的做法(蒸煮两法)
- 使用Quarkus在Openshift上构建微服务的快速指南
- 牛客网 最短路 Floyd算法 Dijkstra算法 Java大数
- PyCharm——turtle库的画布悬停解决方案
- 在Windows系统安装Nodejs
- Pandas库(2):数据的统计分析
- MPEG中面向沉浸式视觉体验的标准化活动
- patator mysql 字典_利用patator进行子域名爆破
- ASP.NET导出word实例
- 安装注册数据库管理工具
- mysql主从同步触发器_Mysql 主从复制触发器问题
- Atitit 获取剪贴板内容
- Word2016以上版本兼容模式不能使用公式编辑器的解决办法
- 传奇服务器端地图链接在哪个文件夹,传奇服务端目录文件详细说明
- 爬虫-python(三) 百度搜索关键词后爬取搜索结果
- macos重启docker
- 神经网络偏置值怎么显示,神经网络的偏置和阈值
- Python调用百度AI接口体验人像动漫化
- .sh文件规则 .sh文件执行方法
- ElasticSearch根据坐标点和半径查询范围内的所有记录,并按距离排序