题目描述 Description###

很久很久以前,有两个长度为 \(n\) 的排列 \(a\) 和 \(b\) 以及一个长度为 \(n\) 的由 \(1\) 和\(2\) 组成的序列 c。对于 \(1<=i<=n\),\(a_i-b_i<=c_i\)。

在岁月中这两个排列早已遗落,只留下了序列 \(c\) 。现在你想要知道满足 \(a_i-b_i<=c_i\) 的方案数,\(a\) 或 \(b\) 某一对应位不同即算不同方案。

由于答案较大,你需要 \(mod 666623333\) 输出。

输入描述 Input Description###

第一行一个整数 \(n\) 。

第二行 \(n\) 个 \(1\) 或 \(2\) 的整数,表示 \(c\) 序列。

输出描述 Output Description###

一个整数,满足条件的方案数 \(mod 666623333\) 。

样例输入 Sample Input###

4
2 1 2 1

样例输出 Sample Output###

296

数据范围及提示 Data Size & Hint###

对于 20%的数据,\(n<=6\) 。

对于 40%的数据,\(n<=10\) 。

对于另外 10%的数据,c 全为 1。

对于另外 20%的数据,c 全为 2。

对于 80%的数据,\(n<=100\) 。

对于 100%的数据,\(1<=n<=2000\) 。

之前的一些废话###

题解###

首先我们可以发现\(C\) 数组中\(1,2\) 的顺序并不重要,重要的是\(1,2\) 的个数。然后由于\(A,B\) 两个都是属于\(1-n\) 的序列,由于\(C\) 数组是针对每一个\(A\) ,$B $ 数的,所以我们不妨定一看一,固定\(A\) 数组来看\(B\) 数组的填法。假设\(A\) 数组是从1到n,然后我们考虑依次往里填数。设\(dp[i][j]\) 表示已经用了\(i\) 个\(1\) ,\(j\) 个\(2\) 的方案数,由于我们是从左到右依次处理的,所以到当前位置,所有B数组的上限已经小于等于当前的数,可以证明:\(A_{i-1}=i-1,B_{i-1}=i\) 或\(i+1\) ,而\(A_i=i,B_i=i+1\) 或\(i+2\),证明了\(B_i \geq B_{i-1}\) ,证明完了这个我们就可以有序的填入B数组了,转移方程为

\(dp[i+1][j]=dp[i+1][j]+dp[i][j]*(min(n,i+j+2)-i-j),
dp[i][j+1]=dp[i][j+1]+dp[i][j]*(min(n,i+j+3)-i-j))\) ,

注意最后答案要乘以\(cnt[1]!*cnt[2]!\)

代码###

#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
typedef long long LL;
inline int read()
{
int x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
const int maxn=2010,MOD=666623333;
int n,cnt[2],dp[maxn][maxn],fac[maxn];
int main()
{
n=read();fac[0]=1;
for(int i=1;i<=n;i++)cnt[read()-1]++;
for(int i=1;i<=n;i++)fac[i]=((LL)fac[i-1]*(LL)i)%MOD;
dp[0][0]=1;
for(int i=0;i<=cnt[0];i++)
for(int j=0;j<=cnt[1];j++)
{
dp[i+1][j]=(dp[i+1][j]+((LL)dp[i][j]*(LL)(min(n,i+j+2)-i-j))%MOD)%MOD;
dp[i][j+1]=(dp[i][j+1]+((LL)dp[i][j]*(LL)(min(n,i+j+3)-i-j))%MOD)%MOD;
}
int t=((LL)fac[cnt[0]]*(LL)fac[cnt[1]])%MOD;
printf("%d\n",((LL)dp[cnt[0]][cnt[1]]*(LL)t)%MOD);
return 0;
}

总结###

像这种排列问题明显就是\(DP\) ,但是关键在于有序的填数进去才能进行正常的\(DP\) ,而且定一看一的思想也是非常重要的。

NOIP模拟赛three(3)的更多相关文章

  1. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  2. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  3. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  4. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

  5. 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...

  6. 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...

  7. 队爷的新书 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的新书 题解:看到这题就想到了 poetize 的封 ...

  8. CH Round #58 - OrzCC杯noip模拟赛day2

    A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...

  9. CH Round #52 - Thinking Bear #1 (NOIP模拟赛)

    A.拆地毯 题目:http://www.contesthunter.org/contest/CH%20Round%20%2352%20-%20Thinking%20Bear%20%231%20(NOI ...

  10. CH Round #49 - Streaming #4 (NOIP模拟赛Day2)

    A.二叉树的的根 题目:http://www.contesthunter.org/contest/CH%20Round%20%2349%20-%20Streaming%20%234%20(NOIP 模 ...

随机推荐

  1. 166. 数独 dancing links 方法

    dfs硬怼通过数独 N皇后的代码后 想学习下新的数据结构和算法来解决这类覆盖问题 习题练习 https://www.acwing.com/problem/content/168/ 数独 https:/ ...

  2. WPF Datagrid 控制 第一行和第一列之间的空白

    原文:WPF Datagrid 控制 第一行和第一列之间的空白 这个位置就是 这里 我们更改 DataGridControltemplate 模板 看树形结构 里面是一个BUtton 功能是全选 能找 ...

  3. 趣谈Linux操作系统学习笔记:第二十八讲

    一.引子 磁盘→盘片→磁道→扇区(每个 512 字节) ext* 定义文件系统的格式 二.inode 与块的存储 1.块 2.不用给他分配一块连续的空间 我们可以分散成一个个小块进行存放 1.优点 2 ...

  4. 跳出"低水平勤奋陷阱"

    "低水平勤奋陷阱":摘记更多的知识 读书是获得知识的最基本,最重要的方式,但读书需要方法 所谓"低水平勤奋陷阱",就是花费了大量的时间和精力,但得到的结果却微乎 ...

  5. SQL Server查询某个表被哪些存储过程调用

    问题描述: 今天有个同事问到如何查询某个表被哪些存储过程调用, 然后同事说可以用SQL search查询,自己试了一下确实可以 sqlsearch下载说明地址:https://www.cnblogs. ...

  6. 常用的app包名和类名

    应用 包名 启动类 QQ com.tencent.mobileqq com.tencent.mobileqq.activity.HomeActivity 微信 com.tencent.mm com.t ...

  7. 写出这个数-PTA

    读入一个正整数 n,计算其各位数字之和,用汉语拼音写出和的每一位数字. 输入格式: 每个测试输入包含 1 个测试用例,即给出自然数 n 的值.这里保证 n 小于 10的100次方. ​​ 输出格式: ...

  8. WPF 使用动画设置特殊值的方法

    例如设置Visibility属性时: 第一种方式: <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIEleme ...

  9. c#图片相关常用的方法及处理

    总结一下图片相关,常用的几个操作   一 创建Image对象 1. 手头上有一些图片文件,希望转换成 c# 中 Image对象,然后加以使用. public static System.Drawing ...

  10. Python中最常见的10个问题(list)

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 大熊 PS:如有需要Python学习资料的小伙伴可以加点击下方链接 ...