题解

一种思路很好想:\(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\) 个区间的学校的数量。

那么转移方程容易得出:

\[f_{i,j}=\left\{
\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}\)

那么最后的转移为

\[f_{i,j}=\sum_{p=1}^{i-1}(^{m+L-1}_{\;\;\;\ m})g_{p,j-1} \;\;\;\ j\in[a_i,b_i]
\]
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]划艇的更多相关文章

  1. P3643 [APIO2016]划艇

    P3643 [APIO2016]划艇 题意 一个合法序列可表示为一个长度为 \(n\) 的序列,其中第 \(i\) 个数可以为 0 或 \([l_i,r_i]\) 中一个整数,且满足所有不为零的数组成 ...

  2. [洛谷P3643] [APIO2016]划艇

    洛谷题目链接:[APIO2016]划艇 题目描述 在首尔城中,汉江横贯东西.在汉江的北岸,从西向东星星点点地分布着 \(N\) 个划艇学校,编号依次为 \(1\) 到 \(N\).每个学校都拥有若干艘 ...

  3. 洛谷P3643 [APIO2016]划艇(组合数学)

    题面 传送门 题解 首先区间个数很少,我们考虑把所有区间离散化(这里要把所有的右端点变为\(B_i+1\)代表的开区间) 设\(f_{i,j}\)表示考虑到第\(i\)个学校且第\(i\)个学校必选, ...

  4. [组合][DP]luogu P3643 [APIO2016]划艇

    题面 https://www.luogu.com.cn/problem/P3643 对于一个序列,第i项可取的值在{0}∪[ai,bi]之间,求使序列非零部分单调递增的方案数 分析 设 $f[i][j ...

  5. 洛谷 P3643 - [APIO2016]划艇(dp)

    题面传送门 一道难度中等的 \(dp\)(虽然我没有想出来/kk). 首先一眼 \(dp_{i,j}\) 表示考虑到第 \(i\) 个学校,第 \(i\) 个学校派出了 \(j\) 个划艇的方案数,转 ...

  6. BZOJ4584 & 洛谷3643 & UOJ204:[APIO2016]划艇——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4584 https://www.luogu.org/problemnew/show/P3643 ht ...

  7. BZOJ 4584 luogu P3643: [Apio2016]赛艇

    4584: [Apio2016]赛艇 Time Limit: 70 Sec  Memory Limit: 256 MB[Submit][Status][Discuss] Description 在首尔 ...

  8. [APIO2016]划艇

    题目描述 在首尔城中,汉江横贯东西.在汉江的北岸,从西向东星星点点地分布着 NNN 个划艇学校,编号依次为 111 到 NNN.每个学校都拥有若干艘划艇.同一所学校的所有划艇颜色相同,不同的学校的划艇 ...

  9. Solution -「APIO 2016」「洛谷 P3643」划艇

    \(\mathcal{Description}\)   Link & 双倍经验.   给定 \(n\) 个区间 \([a_i,b_i)\)(注意原题是闭区间,这里只为方便后文描述),求 \(\ ...

随机推荐

  1. Java基础——自己的总结

    Java Java是什么? Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承.指针等概念,因此Java语言具有功能强大和简单易用两个特征.Java语言作 ...

  2. VS2017 常用快捷键

    项目相关的快捷键 Ctrl + Shift + B = 生成项目 Ctrl + Alt + L = 显示 Solution Explorer(解决方案资源管理器) Shift + Alt+ C = 添 ...

  3. asp.net c#从SQL2008读取图片显示到网页

    //图像数据表:tx//字段id (nvarchar(50) ,image(image)//tgav为图片ID,实质为上传前的主名 (省略了.jpg) using System; using Syst ...

  4. Java基础00-基础知识练习12

    1. 减肥计划 1.1 if语句实现 import java.util.Scanner; public class Demo01 { public static void main(String[] ...

  5. Java基础00-Debug11

    1. Debug 1.1 Debug概述 1.2 Debug操作流程 1.2.1 如何加断点 1.2.2 如何运行加了断点的程序 1.2.3 看哪里 1.2.4 点哪里 1.2.5 如何删除断点 多个 ...

  6. vue如何动态加载本地图片

    大家好,我是前端队长Daotin,想要获取更多前端精彩内容,关注我(全网同名),解锁前端成长新姿势. 以下正文: 今天遇到一个在vue文件中引入本地图片的问题,于是有了这篇文章. 通常,我们的一个im ...

  7. airodump-ng的使用及显示

    PWR   表示所接收的信号的强度.表示为负数,数值赿大表示信号赿强.(绝对值赿大,数据赿值小) beacons  表示网卡接收到的AP发出的信号个数

  8. via浏览器和Alook浏览器插件安装

    via和Alook是Android和IOS上可以支持JS插件的浏览器,一些常用的插件可以在via-app.cn上找到.但总会有人会思考点击安装按钮的是怎样将JS脚本代码安装到浏览器的. 经过对页面代码 ...

  9. Fedora无法安装Qt4

    针对QT4,6安装时遇到的情况 安装平台:fedora14i686 Qt版本:4.6.2 1:解压qt的tar包 我们进行解压(tar xzvf ***.tar.gz),解压到指定目录的话后边加上: ...

  10. Spring Cloud Alibaba基础教程:Sentinel

    随着微服务的流行,服务和服务之间的稳定性变得越来越重要.Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从流量控制.熔断降级.系统自适应保护等多个维度来保障微服务的稳定性. ...