题解 P3643 [APIO2016]划艇
题解
一种思路很好想:\(f_{i,j}\) 表示前 \(i\) 所学校中,第 \(i\) 所学校参赛且派出 \(j\) 艘划艇的方案数。(转移就不列了。)
这种方式有一个致命点,就是 \(j\) 的范围是 \(10^9\),这样连 \(9\) 分都过不去。当我们看到这么大数据范围时,一般想的都是离散化。
此时我们就可以设状态为:\(f_{i,j}\) 表示前 \(i\) 所学校中第 \(i\) 所学校参赛,且派出的划艇数落到第 \(j\) 个区间的方案数。因为一共有 \(n\) 个区间,所以 \(j\) 复杂度最多为 \(\mathcal O(n)\)。
所以在第 \(i\) 所学校之前的学校可以分为两种,在区间 \(j\) 的和不在的。
引理 :
若要从 \([0,L]\) 中选出 \(n\) 个数,其中非零数严格递增,则有 \((^{L+n}_{\kern 0.6em n})\) 种可能
(证明请看别的大佬的题解)
那么对于本题来说,因为我们设的第 \(i\) 所学校必须参赛,所以计算 \(0\) 时答案需要减 \(-1\) ,方案数即为 \((^{m-1+L}_{\;\;\;\ m})\),\(m\) 表示挑选划艇个数在第 \(j\) 个区间的学校的数量。
那么转移方程容易得出:
\begin{array}{l}
\sum_{p=1}^{i-1}\sum_{k=1}^{j-1}(^{m+L-1}_{\;\;\;\ m})f_{p,k} \kern 1.5emj\in [a_i,b_i] \\
0 \kern 10.8emj\notin [a_i,b_i]\\
\end{array}
\right.
\]
对于 \(\sum_{p=1}^{i-1}\sum_{k=1}^{j-1}(^{m+L-1}_{\;\;\;\ m})f_{p,k}\) 我们可以用一个前缀和处理一下
则设 \(g_{i,j}=\sum_{k=1}^{j}f_{i,k}\)
那么最后的转移为
\]
Code
#include<bits/stdc++.h>
#define ri register int
#define p(i) ++i
using namespace std;
namespace IO{
char buf[1<<21],*p1=buf,*p2=buf;
inline char gc() {return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
inline int read() {
ri x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=gc();}
while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=gc();}
return x*f;
}
}
using IO::read;
namespace nanfeng{
#define ll long long
static const int N=550;
static const int MOD=1e9+7;
int inv[N],a[N],b[N],num[N<<1],C[N],g[N],tot,n;
inline int main() {
n=read();
inv[1]=1;
for (ri i(2);i<=n;p(i)) inv[i]=1ll*(MOD-MOD/i)*inv[MOD%i]%MOD;
for (ri i(1);i<=n;p(i)) {
a[i]=read(),b[i]=read();
num[p(tot)]=a[i];num[p(tot)]=b[i]+1;
}
sort(num+1,num+tot+1);
tot=unique(num+1,num+tot+1)-num-1;
for (ri i(1);i<=n;p(i)) {
a[i]=lower_bound(num+1,num+tot+1,a[i])-num;
b[i]=lower_bound(num+1,num+tot+1,b[i]+1)-num;
}
C[0]=g[0]=1;
for (ri j(1);j<tot;p(j)) {
int len=num[j+1]-num[j];
for (ri i(1);i<=n;p(i)) C[i]=(ll)C[i-1]*(ll)(len+i-1)%MOD*inv[i]%MOD;
for (ri i(n);i;--i) {
if (a[i]<=j&&j+1<=b[i]) {
int f=0,cnt=1,l=C[1];
for (ri k(i-1);k>=0;--k) {
f=(f+(ll)l*g[k]%MOD)%MOD;
if (a[k]<=j&&j+1<=b[k]) l=C[p(cnt)];
}
g[i]=(g[i]+f)%MOD;
}
}
}
int ans=0;
for (ri i(1);i<=n;p(i)) ans=(ans+g[i])%MOD;
printf("%lld\n",ans);
return 0;
}
// #undef int
}
int main() {return nanfeng::main();}
复杂度为 \(\mathcal O(n^3)\)
题解 P3643 [APIO2016]划艇的更多相关文章
- P3643 [APIO2016]划艇
P3643 [APIO2016]划艇 题意 一个合法序列可表示为一个长度为 \(n\) 的序列,其中第 \(i\) 个数可以为 0 或 \([l_i,r_i]\) 中一个整数,且满足所有不为零的数组成 ...
- [洛谷P3643] [APIO2016]划艇
洛谷题目链接:[APIO2016]划艇 题目描述 在首尔城中,汉江横贯东西.在汉江的北岸,从西向东星星点点地分布着 \(N\) 个划艇学校,编号依次为 \(1\) 到 \(N\).每个学校都拥有若干艘 ...
- 洛谷P3643 [APIO2016]划艇(组合数学)
题面 传送门 题解 首先区间个数很少,我们考虑把所有区间离散化(这里要把所有的右端点变为\(B_i+1\)代表的开区间) 设\(f_{i,j}\)表示考虑到第\(i\)个学校且第\(i\)个学校必选, ...
- [组合][DP]luogu P3643 [APIO2016]划艇
题面 https://www.luogu.com.cn/problem/P3643 对于一个序列,第i项可取的值在{0}∪[ai,bi]之间,求使序列非零部分单调递增的方案数 分析 设 $f[i][j ...
- 洛谷 P3643 - [APIO2016]划艇(dp)
题面传送门 一道难度中等的 \(dp\)(虽然我没有想出来/kk). 首先一眼 \(dp_{i,j}\) 表示考虑到第 \(i\) 个学校,第 \(i\) 个学校派出了 \(j\) 个划艇的方案数,转 ...
- BZOJ4584 & 洛谷3643 & UOJ204:[APIO2016]划艇——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4584 https://www.luogu.org/problemnew/show/P3643 ht ...
- BZOJ 4584 luogu P3643: [Apio2016]赛艇
4584: [Apio2016]赛艇 Time Limit: 70 Sec Memory Limit: 256 MB[Submit][Status][Discuss] Description 在首尔 ...
- [APIO2016]划艇
题目描述 在首尔城中,汉江横贯东西.在汉江的北岸,从西向东星星点点地分布着 NNN 个划艇学校,编号依次为 111 到 NNN.每个学校都拥有若干艘划艇.同一所学校的所有划艇颜色相同,不同的学校的划艇 ...
- Solution -「APIO 2016」「洛谷 P3643」划艇
\(\mathcal{Description}\) Link & 双倍经验. 给定 \(n\) 个区间 \([a_i,b_i)\)(注意原题是闭区间,这里只为方便后文描述),求 \(\ ...
随机推荐
- Java并发实战一:线程与线程安全
从零开始创建一家公司 Java并发编程是Java的基础之一,为了能在实践中学习并发编程,我们跟着创建一家公司的旅途,一起来学习Java并发编程. 进程与线程 由于我们的目标是学习并发编程,所以我不会把 ...
- idea本地调式tomcat源码
前言 上篇文章中一直没搞定的tomcat源码调试终于搞明白了,p神的代码审计星球里竟然有,真的好b( ̄▽ ̄)d ,写一下过程,还有p神没提到的小坑 准备阶段 1.去官网下东西:https://tomc ...
- 牛客OI测试赛1
题目链接: https://www.nowcoder.com/acm/contest/181#question A.斐波拉契 求$f[n-1]*f[n+1]-f[n]^2$,$f[n]$为斐波拉契数列 ...
- Unittest方法 -- 测试断言
"""断言详解"""from unittest_1.it import *def add(a,b): return a - bclass B ...
- 安装Go语言支持及Gogs版本管理工具
安装Go语言支持及Gogs版本管理工具 1. GO 语言: 1.1 介绍 1.1.1 官方介绍: The Go programming language is an open source proje ...
- Linux文件浏览(less、more、head、tail)以及vim编辑器命令总结
结合小编学习实践,整理了Linux下查看内容(less.more.head.tail)和编辑内容(vim)的部分基础命令解析: 1.less命令 分页浏览内容,如果在shell命令行下按回车键,则一点 ...
- Linkerd 金丝雀部署与 A/B 测试
本指南向您展示如何使用 Linkerd 和 Flagger 来自动化金丝雀部署与 A/B 测试. 前提条件 Flagger 需要 Kubernetes 集群 v1.16 或更新版本和 Linkerd ...
- Python自动化测试面试题-MySQL篇
目录 Python自动化测试面试题-经验篇 Python自动化测试面试题-用例设计篇 Python自动化测试面试题-Linux篇 Python自动化测试面试题-MySQL篇 Python自动化测试面试 ...
- 如何获取SQL Server数据库连接字符串的某些部分
有的时候需要获取SQL Server数据库连接字符串的某些部分.用正则表达式可能有点麻烦. 其实有一个比较简单的方法--使用SqlConnectionStringBuilder. var builde ...
- Java书单-比较全的一篇
本文已收录至码云:https://gitee.com/jalon2015/java-book 前言 之前写过一篇,Java核心书单,里面涵盖了几本主要的Java书籍: 后来有朋友反馈说,这几本太少了, ...