spoj periodni
题解:
dp
方程弄出来就好做了
代码:
#include<bits/stdc++.h>
const int N=,M=;
typedef int arr[N];
typedef long long ll;
int n,k,c[N][N],h[N];
arr g;
void add(int &x,int y){x+=y;if (x>=M)x-=M;}
void dfs(int l,int r,int H,arr &ans)
{
memset(ans,,sizeof(ans));
ans[]=;
int p=l,m=r-l+;
for (int i=l;i<=r;i++)
if (h[i]<h[p]) p=i;
arr L,R;
L[]=R[]=;
int h0=H;H=h[p]-H;
if (l<p)dfs(l,p-,h[p],L);
if (p<r)dfs(p+,r,h[p],R);
memset(g,,sizeof(g));
for (int i=;i<=p-l;i++)
for (int j=m;j>=i;j--)
(g[j]+=(ll)ans[j-i]*L[i]%M)%=M;
memcpy(ans,g,sizeof(ans));
memset(g,,sizeof(g));
for (int i=;i<=r-p;i++)
for (int j=m;j>=i;j--)
(g[j]+=(ll)ans[j-i]*R[i]%M)%=M;
memcpy(ans,g,sizeof(ans));
memset(g,,sizeof(g));
ll P=;
for (int i=;i<=m&&i<=H;i++)
{
for (int j=m;j>=i;j--)
(g[j]+=(ll)ans[j-i]*c[m-j+i][i]%M*P%M)%=M;
P=P*(H-i)%M;
}
memcpy(ans,g,sizeof(ans));
}
int main()
{
scanf("%d%d",&n,&k);
for (int i=;i<=n;i++)scanf("%d",&h[i]);
c[][]=;
for (int i=;i<=;i++)
{
c[i][]=;
for (int j=;j<=i;j++)
c[i][j]=(c[i-][j]+c[i-][j-])%M;
}
arr ans;
dfs(,n,,ans);
printf("%d\n",ans[k]);
return ;
}
spoj periodni的更多相关文章
- [BZOJ2616]SPOJ PERIODNI 树形dp+组合数+逆元
2616: SPOJ PERIODNI Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 128 Solved: 48[Submit][Status][ ...
- 【BZOJ2616】SPOJ PERIODNI 笛卡尔树+树形DP
[BZOJ2616]SPOJ PERIODNI Description Input 第1行包括两个正整数N,K,表示了棋盘的列数和放的车数. 第2行包含N个正整数,表示了棋盘每列的高度. Output ...
- BZOJ.2616.SPOJ PERIODNI(笛卡尔树 树形DP)
BZOJ SPOJ 直观的想法是构建笛卡尔树(每次取最小值位置划分到两边),在树上DP,这样两个儿子的子树是互不影响的. 令\(f[i][j]\)表示第\(i\)个节点,放了\(j\)个车的方案数. ...
- BZOJ2616 SPOJ PERIODNI(笛卡尔树+树形dp)
考虑建一棵小根堆笛卡尔树,即每次在当前区间中找到最小值,以最小值为界分割区间,由当前最小值所在位置向两边区间最小值所在位置连边,递归建树.那么该笛卡尔树中的一棵子树对应序列的一个连续区间,且根的权值是 ...
- BZOJ2616 : SPOJ PERIODNI
长为$A$,宽为$B$的矩阵放$K$个车的方案数$=C(A,K)\times C(B,K)\times K!$. 建立笛卡尔树,那么左右儿子独立,设$f[i][j]$表示$i$子树内放$j$个车的方案 ...
- bzoj2616: SPOJ PERIODNI——笛卡尔树+DP
不连续的处理很麻烦 导致序列DP又找不到优秀的子问题 自底向上考虑? 建立小根堆笛卡尔树 每个点的意义是:高度是(自己-father)的横着的极大矩形 子问题具有递归的优秀性质 f[i][j]i为根子 ...
- bzoj 2616 SPOJ PERIODNI——笛卡尔树+树形DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2616 把相同高度的连续一段合成一个位置(可能不需要?),用前缀和维护宽度. 然后每次找区间里 ...
- BZOJ2616 SPOJ PERIODNI(笛卡尔树 + DP)
题意 N,K≤500,h[i]≤106N,K\le 500,h[i]\le10^6N,K≤500,h[i]≤106 题解 建立出小根堆性质的笛卡尔树,于是每个节点可以代表一个矩形,其宽度为子树大小,高 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
随机推荐
- cocos2dx JS 图片精灵添加纹理缓存
添加精灵图片缓存 : cc.spriteFrameCache.addSpriteFrames("res/pic.plist"); 从缓存中获取 : var frame = cc.s ...
- git之概念图
1.git四大区. . 2. 3. 4.
- git之关联远程仓库
1.创建本地仓库. 2.与远程仓库交互. ----------------------------------------------------------------------------
- ATM Mechine (概率DP)
题意:去银行取最多K钱,想要全部取完,但是有个限制就是如果你输入取钱的额度超过了你已有的钱,那么会接受一次警告并无法取钱,然后求最多不超过w次警告的前提下你取完所有钱所需要的最少次数. 思路:概率DP ...
- C++ Com控件调用
1.假如我们创建的Com组件的工程名叫TestCom,在其中添加了一个接口叫MyCom,接口名会自动命名为IMyCom,在其中添加两个方法,分别为: HRESULT Add([in] long n1, ...
- Vue基础进阶 之 实例方法--生命周期
在上一篇博客中我们知道生命周期的方法: 生命周期: vm.$mount:手动挂载Vue实例: vm.$destroy:销毁Vue实例,清理数据绑定,移除事件监听: vm.$nextTick:将方法中的 ...
- JavaScript 序列化、转义
JavaScript 序列化.转义 序列化 // 将对象转换为字符串 JSON.stringify() // 将字符串转换为对象类型 JSON.parse() 转义 // URl中未转义的字符 de ...
- VC++ 实现INI文件读写操作
转载:https://blog.csdn.net/fan380485838/article/details/73188420 在实际项目开发中,会用ini配置文件,在此总结一下对ini读写操作 一:读 ...
- ubuntu14.04 anaconda tensorflow spyder(python3.5) + opencv3
windows上用的tensorflow是依赖于python3.5,因此在linux下也配的3.5 一. 在Anaconda官网上下载Anaconda3-4.0.0-Linux-x86_64.sh文件 ...
- LINQ之路12:LINQ Operators之数据转换(Projecting)
本篇继续LINQ Operators的学习,这里我们讨论的是数据转换的两种方式:Select和SelectMany,看似简单常用的两种运算符,却也大有讲究.我们会在本篇详细介绍他们的使用方式和适用的场 ...