P3643 [APIO2016]划艇

题意

一个合法序列可表示为一个长度为 \(n\) 的序列,其中第 \(i\) 个数可以为 0 或 \([l_i,r_i]\) 中一个整数,且满足所有不为零的数组成的子序列严格上升。求合法序列方案数。

思路

朴素动态规划做法为,设 \(f_{ij}\) 表示第 \(i\) 个数不为零且数量为 \(j\) 的方案数,则

\[ans=\sum_{i=1}^n\sum_{j=l_i}^{r_i}f_{ij}\\
f_{ij}=\sum_{k=1}^{j-1}\sum_{q=0}^{i-1}f_{qk},j\in[l_i,r_i]
\]

但是第二维枚举太多。考虑优化。

首先,我们考虑一段区间,按照上面的方式递推需要依次枚举数量再枚举 \(i-1\) 个数的方案进行转移,不能够简化的主要原因是因为每个数都有一个限定的区间。若不加限定,发现这段转移可以简化为一个简单问题:每个数可以选取值范围内任意的值或 0,求所有不为零的数组成的子序列严格上升方案数。设取值区间大小为 \(len\),数的数量为 \(n\),则答案为 \(\binom{len+n}n\)。可以理解为额外增加 \(n\) 个 0 表示选 0。

所以我们进行离散化,将取值范围分为若干段,每个数的范围由若干这样的段组成。对于每一段我们都可以按照上面的方法转移。即对于这一段区间 \(j\),对于所有包含它的数字,可以从 \(0\) 到 \(i-1\) 中任意一种状态 \(k\) 转移得到,并且需要乘上在 \(k\) 到 \(i\) 中选任意个区间包含 \(j\) 的数字不为 0 的方案数,即 \(\binom{len+m-1}m\) 其中 \(m\) 为上述数的个数,\(len\) 为第 \(j\) 段的长度,减 1 是因为第 \(i\) 个必选。即

\[ans=\sum_{i=1}^n\sum_{j=l_i}^{r_i}f_{ij}\\
f_{ij}=\sum_{q=0}^{i-1}\binom{len+m_{jq}-1}{m_{jq}}\sum_{k=1}^{j-1}f_{qk},j\in[l_i,r_i],m_{jq}=\sum_{o=q+1}^i[j\in[l_o,r_o]],len为区间j的长度
\]

发现后面的求和维护一个前缀和即可。总时间复杂度 \(O(n^3)\)。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cctype>
#include<cstring>
#include<cmath>
using namespace std;
inline int read(){
int w=0,x=0;char c=getchar();
while(!isdigit(c))w|=c=='-',c=getchar();
while(isdigit(c))x=x*10+(c^48),c=getchar();
return w?-x:x;
}
namespace star
{
const int maxn=505,mod=1e9+7;
int n,m,l[maxn],r[maxn],b[maxn<<1],C[maxn],inv[maxn],f[maxn],ans;
inline void work(){
n=read();
inv[1]=1;for(int i=2;i<=n;i++) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
for(int i=1;i<=n;i++) l[i]=b[(i<<1)-1]=read(),r[i]=b[i<<1]=read(),b[i<<1]++;
sort(b+1,b+1+(n<<1));
m=unique(b+1,b+1+(n<<1))-b-1;
for(int i=1;i<=n;i++) l[i]=lower_bound(b+1,b+1+m,l[i])-b,r[i]=lower_bound(b+1,b+1+m,r[i]+1)-b;
C[0]=f[0]=1;
for(int j=1;j<m;j++){
int len=b[j+1]-b[j];
for(int i=1;i<=n;i++) C[i]=1ll*C[i-1]*(len+i-1)%mod*inv[i]%mod;
for(int i=n;i;i--) if(l[i]<=j and r[i]>=j+1){
int cnt=1;
for(int k=i-1;~k;k--) f[i]=(f[i]+1ll*C[cnt]*f[k])%mod,cnt+=l[k]<=j and r[k]>=j+1;
}
}
for(int i=1;i<=n;i++) ans=(ans+f[i])%mod;
printf("%d\n",ans);
}
}
signed main(){
star::work();
return 0;
}

P3643 [APIO2016]划艇的更多相关文章

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

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

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

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

  3. 题解 P3643 [APIO2016]划艇

    题解 一种思路很好想:\(f_{i,j}\) 表示前 \(i\) 所学校中,第 \(i\) 所学校参赛且派出 \(j\) 艘划艇的方案数.(转移就不列了.) 这种方式有一个致命点,就是 \(j\) 的 ...

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

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

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

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

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

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

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

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

  8. [APIO2016]划艇

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

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

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

随机推荐

  1. 一文讲全了Python 类和对象内容

    摘要:这是一个关于 Python 类和对象的全部内容. 本文分享自华为云社区<从零开始学python | Python 类和对象-面向对象编程>,原文作者:Yuchuan  . Pytho ...

  2. 彻底删除Docker

    yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-la ...

  3. 「题解」黑暗塔 wizard

    本文将同步发布于: 洛谷博客: csdn: 博客园: 简书. 题目 题意简述 给定 \(y\),求 \(\varphi(x)=y\) 中 \(x\) 的个数和最大值. \(1\leq y\leq 10 ...

  4. 基于Colab Pro & Google Drive的Kaggle实战

    原文:https://hippocampus-garden.com/kaggle_colab/ 原文标题:How to Kaggle with Colab Pro & Google Drive ...

  5. csp-s模拟测试49(9.22)养花(分块/主席树)·折射(神仙DP)·画作

    最近有点头晕........... T1 养花 考场我没想到正解,后来打的主席树,对于每个摸数查找1-(k-1),k-(2k-1)...的最大值,事实上还是很容易被卡的但是没有数据好像还比较友善, 对 ...

  6. noip2010 总结

    机器翻译 题目背景 小晨的电脑上安装了一个机器翻译软件,他经常用这个软件来翻译英语文章. 题目描述 这个翻译软件的原理很简单,它只是从头到尾,依次将每个英文单词用对应的中文含义来替换.对于每个英文单词 ...

  7. Telnet查看端口是否通

    1. 查看端口是否通畅   telnet IP 端口号 如:telnet 10.150.159.71 5516 2.查看本机是否开启某个端口:netstat -an |findstr "端口 ...

  8. git 认证问题之一的解决 : http ssh 互换

    场景 使用git 我们经常会遇到 认证失败的情况,有时候确实是搞错了用户名或者密码,还有的时候及时用户名密码用对了也还是认证失败. 此时, 就有可能是下面这个情况. 没有配置 ssh 秘钥, 而用了 ...

  9. 通过UnityWebRequest得到的纹理转精灵

    private IEnumerator GetImage(string url, Image fileImage) { UnityWebRequest WebRequest = new UnityWe ...

  10. Ubuntu18.04 LTS x64 构建ARM交叉编译环境(尝试,但失败了!!!估计是编译器没选对)

    [测试而已,由于需要了解编译器和处理器体系,因此先放弃该方法] 动机 入门嵌入式开发,又需要 Windows 又需要 Linux,但资料给的竟然是 Ubuntu9,导致我不能使用 VSCode Rem ...