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. noip2009 总结

    潜伏者 原题 R 国和 S 国正陷入战火之中,双方都互派间谍,潜入对方内部,伺机行动.历尽艰险后,潜伏于 S 国的 R 国间谍小 C 终于摸清了 S 国军用密码的编码规则:1. S 国军方内部欲发送的 ...

  2. Golang学习(用代码来学习) - 第二篇

    type Circle struct { radius float64 desc string } //定义结构体里面的方法 func (c Circle) getArea() float64 { r ...

  3. redis学习第一天

    不同于其他的常用关系型数据库,redis是一个非常轻便,体积小,存放键值对的数据库,常用于构建高性能,可扩展的Web应用程序. 这是我第一次接触redis,之前没有使用过,只听说过.因为刚毕业,找工作 ...

  4. 基于ABP落地领域驱动设计-05.实体创建和更新最佳实践

    目录 系列文章 数据传输对象 输入DTO最佳实践 不要在输入DTO中定义不使用的属性 不要重用输入DTO 输入DTO中验证逻辑 输出DTO最佳实践 对象映射 学习帮助 系列文章 基于ABP落地领域驱动 ...

  5. excel计数函数COUNTIF、COUNTIFS

    1.单条件计数:COUNTIF(条件区域,指定条件) =COUNTIF($H$2:$H$8,L2)求H2:H8中值等于L2的行记录数,这里求的是游泳项目总共有多少个人参加 2.多条件计数:COUNTI ...

  6. 创建Cloudflare CDN

    背景说明: XX全球版项目CDN, 原有改之前:主CDN为Akamai,备CDN为Cloudflare. 计划改之后:主CDN为Cloudflare,备CDN为Akamai. 原因:Akamai CD ...

  7. error C3646: 未知重写说明符

    记录一个报错 error C3646: 未知重写说明符 ①循环引用 在项目文件变多时,由于组织不当,很容易出现头文件的循环引用 有时候虽然没有出现循环引用,但是头文件多处被include :适当的使用 ...

  8. 6.11、制作windos虚拟机

    1.下载kvm支持windows系统的驱动程序: cd /tmp/ wget https://fedorapeople.org/groups/virt/virtio-win/direct-downlo ...

  9. js jquey 笔记

    1.使用insertAfter 如果插入在tr后添加多行数据,数据会倒过来注意组字符串需要倒着循环 1).html方法,给元素添加html代码或者清空html代码(参数为空字符串): 2).appen ...

  10. ICMP路由重定向攻击

    ICMP介绍 ICMP(Internet Control Message Protocol)Internet控制报文协议.它是TCP/IP协议簇的一个子协议,用于在IP主机.路由器之间传递控制消息.控 ...