【xsy1503】 fountain DP
题目大意:给你$D$个格子,有$n$个喷水器,每个喷水器有一个喷水距离$r_i$。
现在你需要在这$D$个格子中选择$n$个位置按照任意顺序安装这$n$个喷水器,需要满足$n$个喷水器互相喷不到对方。
问方案数,对$10^9+7$取模
数据范围:$n$,$r_i≤40$,$D≤10^5$
我们不妨考虑我们钦定了这$n$个喷水器的出现顺序,从左到右第$i$个喷水器编号为$p[i]$。
确定排列顺序后,令$d=\sum \limits_{i=1}^{n-1} max(r_{p[i]},r_{p[i+1]})$
我们发现上式累加的实际上是相邻两个喷水器之间的最小间隔
我们尝试把这个间隔中的格子看成是一个格子。
我们就可以把原序列中$D$个格子看成是$D-d-1$个了。
现在也就是变成了要在这剩下的格子之间插入这$n$个喷水器,方案数显然为$\binom{D-d-1+n}{n}$。
下面考虑如何求不同的排列顺序数量。
我们先将$n$个喷水器按照喷水半径进行排序。
设$f[i][j][k]$表示前i个喷水器必须出现,且这$i$个喷水器间(包括两端),有$j$个可以插入喷水器,且由这些喷水器累加出的$d$为$k$的方案数量。
下面考虑在$f[i][j][k]$的基础上插入第$i+1$个喷水器。
假定这个喷水器插入后,两侧不能再插入喷水器,则有$f[i+1][j-1][k+2r_{i+1}]+=f[i][j][k]\times (j-2)$
假定这个喷水器插入后,只有一侧能插入喷水器,则有$f[i+1][j][k+r_{i+1}]+=f[i][j][k]\times (2j-2)$
上面两个转移需要$-2$的原因显然(并不能允许最左侧和最右侧插入喷水器)
假定这个喷水器插入后,两侧皆可以插入喷水器,则有$f[i+1][j+1][k]+=f[i][j][k]\times j$
初始情况:$f[1][2][0]=1$,答案为$\sum \limits_{i=1}^{\infty} f[n][2][i]$
转移和答案统计的时候记得取模即可
时间复杂度:$O(n^2\sum \limits_{i=1}^{n} r_i)$
#include<bits/stdc++.h>
#define M 42
#define N 110000
#define L long long
#define MOD 1000000007
using namespace std; L pow_mod(L x,L k){L ans=; for(;k;k>>=,x=x*x%MOD) if(k&) ans=ans*x%MOD; return ans;}
L fac[N]={},invfac[N]={};
L C(int n,int m){if(n-m<) return ; return fac[n]*invfac[m]%MOD*invfac[n-m]%MOD;} int n,D,r[M]={};
L f[M][M][M*M]={}; int main(){
fac[]=; for(int i=;i<N;i++) fac[i]=fac[i-]*i%MOD;
invfac[N-]=pow_mod(fac[N-],MOD-);
for(int i=N-;~i;i--) invfac[i]=invfac[i+]*(i+)%MOD; scanf("%d%d",&n,&D);
for(int i=;i<=n;i++) scanf("%d",r+i);
sort(r+,r+n+);
f[][][]=;
for(int i=;i<n;i++)
for(int j=;j<=n+;j++)
for(int k=;k<M*M;k++)
if(f[i][j][k]){
(f[i+][j+][k]+=f[i][j][k]*j)%=MOD;
if(j>) (f[i+][j-][k+*r[i+]]+=f[i][j][k]*(j-))%=MOD;
if(j>) (f[i+][j][k+r[i+]]+=f[i][j][k]*(*j-))%=MOD;
}
L ans=;
for(int d=;d<M*M;d++)
if(f[n][][d]){
(ans+=C(D-d-+n,n)*f[n][][d])%=MOD;
}
cout<<ans<<endl;
}
【xsy1503】 fountain DP的更多相关文章
- LG4719 【模板】动态dp 及 LG4751 动态dp【加强版】
题意 题目描述 给定一棵\(n\)个点的树,点带点权. 有\(m\)次操作,每次操作给定\(x,y\),表示修改点\(x\)的权值为\(y\). 你需要在每次操作之后求出这棵树的最大权独立集的权值大小 ...
- 【专题】数位DP
[资料] ★记忆化搜索:数位dp总结 之 从入门到模板 by wust_wenhao 论文:浅谈数位类统计问题 数位计数问题解法研究 [记忆化搜索] 数位:数字从低位到高位依次为0~len-1. 高位 ...
- 洛谷P4719 【模板】"动态 DP"&动态树分治
[模板]"动态 DP"&动态树分治 第一道动态\(DP\)的题,只会用树剖来做,全局平衡二叉树什么的就以后再学吧 所谓动态\(DP\),就是在原本的\(DP\)求解的问题上 ...
- LG5056 【模板】插头dp
题意 题目背景 ural 1519 陈丹琦<基于连通性状态压缩的动态规划问题>中的例题 题目描述 给出n*m的方格,有些格子不能铺线,其它格子必须铺,形成一个闭合回路.问有多少种铺法? 输 ...
- 【专题】区间dp
1.[nyoj737]石子合并 传送门:点击打开链接 描述 有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这 ...
- 【BZOJ4976】宝石镶嵌 DP
[BZOJ4976]宝石镶嵌 Description 魔法师小Q拥有n个宝石,每个宝石的魔力依次为w_1,w_2,...,w_n.他想把这些宝石镶嵌到自己的法杖上,来提升法杖的威力.不幸的是,小Q的法 ...
- NOJ 1111 保险箱的密码 【大红】 [区间dp]
传送门 保险箱的密码 [大红] 时间限制(普通/Java) : 1000 MS/ 3000 MS 运行内存限制 : 65536 KByte总提交 : 118 测 ...
- 【CF480D】Parcels DP
[CF480D]Parcels 题意:有一个栈,有n个物品,每个物品可以选或不选.如果选了第i个物品,则获得$v_i$的收益,且第i个物品必须在$in_i$时刻入栈,$out_i$时刻出栈.每个物品还 ...
- 【BZOJ4621】Tc605 DP
[BZOJ4621]Tc605 Description 最初你有一个长度为 N 的数字序列 A.为了方便起见,序列 A 是一个排列. 你可以操作最多 K 次.每一次操作你可以先选定一个 A 的一个子串 ...
随机推荐
- C++ 常见术语及解释
RAII(Resource Acquisition Is Initialization) 资源获取就是初始化 RTTI(Run-time type information) 运行时类型信息 RVO(R ...
- 什么是PLI?
首先,什么是PLI? 本部分设定了隐藏,您已回复过了,以下是隐藏的内容 PLI 就是product liability insurance 的简写,中文可以翻译成“产品责任险”说白了,就是你的产品如果 ...
- mysql学习笔记--列属性
一.是否为空----null || not null 二.默认值----default 三.自动增长----auto_increment 四.主键----primary key 1. 主键:唯一标识表 ...
- react官方脚手架搭建项目
1.全局安装 npm install -g create-react-app 2. app后面还要给项目文件命名 create-react-app //是全局命令来创建react项目 3.然后按照提示 ...
- 解决IE浏览器缓存导致AJAX请求数据异常
IE10浏览器会把AJAX请求的数据都缓存下来,然后每次想去刷新数据时发现数据都是一样的,于是导致数据显示异常. 解决方法: 在页面<head>标签里,加上以下声明: <!-- 解决 ...
- 【转】Cron表达式详解
Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式: (1) Seconds Minutes Hours DayofMonth Mo ...
- github管理项目
1.在GitHub上创建一个项目,然后拷贝git地址. 2.在本地打开GIT CMD,然后建立一个文件夹,输入git clone 上面拷贝的git地址. 3.文件夹下会多出一个以你创建的项目名字的文件 ...
- 服务器重新启动,ftp重新连接问题
服务器重新启动,发现FlashFXP无法连接了,估计是ftp没有启动, 1. 首先服务器要安装ftp软件,查看是否已经安装ftp软件下: #which vsftpd 如果看到有vsftpd的目 ...
- python基础之Day13
一.有参装饰器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 ...
- Python之RabbitMQ的使用
今天总结一下Python关于Rabbitmq的使用 RabbitMQ官网说明,其实也是一种队列,那和前面说的线程queue和进程queue有什么区别呢? 线程queue只能在同一个进程下进行数据交互 ...