题目

将互不相同的 \(n\) 个数重排,使得相邻两数差的总和不超过 \(L\) 的有多少种方式。

\(n\leq 100,L\leq 1000\)


分析

对于排列的问题,有一种很妙的方法就是从小到大插入,

若升序数列 \(B\),\(B_{i+1}-B_i\) 对答案产生贡献

当且仅当相邻两数 \(x\leq B_i,y\geq B_{i+1}\)

那么在 \(B_1\) 到 \(B_i\) 排列后可以添加的位置就能产生贡献,

也就是与段数有关,而且要考虑左右边界。

设 \(dp[i][j][k][opt]\) 表示升序后前 \(i\) 个数,依次被分成 \(j\) 段,

目前确定 \(opt\) 个边界(边界不能新开一段),总和为 \(k\) 的方案数。

由 \(i-1\) 过渡到 \(i\) 的贡献即是 \(t=(j*2-opt)*(B_{i}-B_{i-1})\)

  1. 新开一段(不充当边界): \(dp[i][j+1][k][opt]+=dp[i-1][j][k-t][opt]*(j+1-opt)\)

  2. 合并一段:\(dp[i][j-1][k][opt]+=dp[i-1][j][k-t][opt]*(j-1)\)

  3. 将这个数放在段首或段尾(不包含边界): \(dp[i][j][k][opt]+=dp[i-1][j][k-t][opt]*(j*2-opt)\)

  4. 将这个数新开一段并作为边界: \(dp[i][j+1][k][opt+1]+=dp[i-1][j][k-t][opt]*(2-opt)\)

  5. 将这个数作为边界但不新开一段: \(dp[i][j][k][opt+1]+=dp[i-1][j][k-t][opt]*(2-opt)\)

最后答案为 \(\sum_{i=0}^L dp[n][1][i][2]\),注意当 \(n=1\) 时要特判。


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;
const int N=111,mod=1000000007;
int dp[N][N][N*10][3],n,m,a[N],ans;
int iut(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
void Mo(int &x,int y){x=x+y>=mod?x+y-mod:x+y;}
int main(){
n=iut(),m=iut();
if (n==1) return !printf("1");
for (int i=1;i<=n;++i) a[i]=iut();
sort(a+1,a+1+n),a[0]=a[1];
dp[0][0][0][0]=1;
for (int i=1;i<=n;++i)
for (int j=0;j<i;++j)
for (int opt=0;opt<3;++opt){
if (j*2<opt) break;
int t=(j*2-opt)*(a[i]-a[i-1]);
for (int k=t;k<=m;++k)
if (dp[i-1][j][k-t][opt]){
int now=dp[i-1][j][k-t][opt];
Mo(dp[i][j+1][k][opt],(j+1ll-opt)*now%mod);
Mo(dp[i][j][k][opt],(j*2ll-opt)*now%mod);
if (j) Mo(dp[i][j-1][k][opt],(j-1ll)*now%mod);
if (opt==2) continue;
Mo(dp[i][j+1][k][opt+1],(2ll-opt)*now%mod);
Mo(dp[i][j][k][opt+1],(2ll-opt)*now%mod);
}
}
for (int i=0;i<=m;++i) Mo(ans,dp[n][1][i][2]);
return !printf("%d",ans);
}

#dp,排列#LOJ 2743「JOI Open 2016」摩天大楼的更多相关文章

  1. [LOJ#2743][DP]「JOI Open 2016」摩天大楼

    题目传送门 DP 经典题 考虑从小到大把数加入排列内 如下图(\(A\) 已经经过排序): 我们考虑如上,在 \(i\) ( \(A_i\) )不断增大的过程中,维护上面直线 \(y=A_i\) 之下 ...

  2. [题解] [LOJ2743]「JOI Open 2016」摩天大楼

    题目大意 将 \(N\) 个互不相同的整数 \(A_1 , A_2 , ⋯ , A_N\) 任意排列成 \(B_1 , B_2 , ⋯ , B_N\) . 要求 \(∑^{N−1}_{i=1} |B_ ...

  3. LOJ#2351. 「JOI 2018 Final」毒蛇越狱

    LOJ#2351. 「JOI 2018 Final」毒蛇越狱 https://loj.ac/problem/2351 分析: 首先有\(2^{|?|}\)的暴力非常好做. 观察到\(min(|1|,| ...

  4. LOJ#2764. 「JOI 2013 Final」JOIOI 塔

    题目地址 https://loj.ac/problem/2764 题解 真的想不到二分...不看tag的话... 考虑二分答案转化为判定问题,那么问题就变成了能不能组合出x个JOI/IOI,考虑贪心判 ...

  5. loj 3014「JOI 2019 Final」独特的城市

    loj 我本来是直接口胡了一个意思一样的做法的,但是因为觉得有点假+实现要用并查集(?)就卡了好一会儿... 对于一个点\(x\)来说,独特的点一定在它的最长链上,如果有独特的点不在最长链上,那么最长 ...

  6. loj 2759「JOI 2014 Final」飞天鼠

    loj 这题有在一棵树上上升或者下降的操作,稍加分析后可以发现上升操作如果不是一定要做(指高度不足以到下一棵树或者是最后到达\(n\))就不做,下降操作也是如果不是一定要做(指到达下一棵树时高度过高) ...

  7. loj 2336「JOI 2017 Final」绳

    loj 首先,所有位置最多被染色一次,因为要染多次的话,还不如一开始就染成最终的颜色.并且你可以一开始就染好色 因为最终长度为2,那么如果染完后这个序列可以被折完,那么首先最多只有两种颜色,还有就是要 ...

  8. loj#2334 「JOI 2017 Final」JOIOI 王国

    分析 二分答案 判断左上角是否满足 为了覆盖所有范围 我们依次把右下角,左上角,右上角移动到左上角 代码 #include<bits/stdc++.h> using namespace s ...

  9. loj#2333 「JOI 2017 Final」准高速电车

    分析 我们发现到达一个点一定是先快车再准快车再慢车 于是快车将1-n分为多个区间 每次取出每个区间当前能到达的点的数量 选剩余时间贡献最大的的一个取得贡献并且再能到达的最远点建立准快车 代码 #inc ...

  10. loj#2332 「JOI 2017 Final」焚风现象

    分析 我们发现改变一个区间实际上只有两个端点的贡献变换 代码 #include<bits/stdc++.h> using namespace std; #define int long l ...

随机推荐

  1. MySQL重新设置auto_increment值

    需求描述 通常,我们都会在数据库表中设置一个自增字段作为主键,该字段的值会随着添加新记录而自增. 同时也必须注意,这个自增字段的值只会一直增加,即使把记录删除了,该自增字段的值也不会变小. 因此,就会 ...

  2. pycharm中如何改变主题

    这边分享一个我自己在用的主题,蛮简约的,关键字高亮显示.再也不用全都是一样的颜色了.网盘地址在最后哈 好了话不多说,教大家如何把主题设置到pycharm中 图1:首先把主题jar包下载下来,然后打开p ...

  3. 【算法day2】复杂度和简单排序算法(2)

    插入排序 有以下数组 数组:[2,4,3,6,1] 序号:[0,1,2,3,4] 第一次排序(范围0~0):2左边没东西,不动 第二次排序(范围0~1):4左边是2,4大不动 第三次排序(范围0~2) ...

  4. 【Azure 环境】前端Web通过Azure AD获取Token时发生跨域问题(CORS Error)

    问题描述 前端Web在开发时使用Azure AD中注册Application的方式进行Token获取,遇到了CORS遇到的问题(如下图).随后在AAD增加了单页应用的重定向URL, 依旧还是出现COR ...

  5. 【Azure 应用服务】[App Service For Linux(Function) ] Python ModuleNotFoundError: No module named 'MySQLdb'

    问题描述 在使用Azure Function创建新的Python Function时,使用MySQLdb连接数据库时候出现 ModuleNotFoundError: No module named ' ...

  6. 浅析图数据库 Nebula Graph 数据导入工具——Spark Writer

    从 Hadoop 说起 近年来随着大数据的兴起,分布式计算引擎层出不穷.Hadoop 是 Apache 开源组织的一个分布式计算开源框架,在很多大型网站上都已经得到了应用.Hadoop 的设计核心思想 ...

  7. [C++/QT] 获取进程完整路径

    气哭我了,我不就获取一下进程路径嘛,,,绕了好大一圈 主要是用到了GetModuleFileNameEx() 函数 食用方式如下 HANDLE hProcess = OpenProcess(PROCE ...

  8. 没想到,JDBC 驱动会偷偷修改 sql_mode 的会话值

    最近碰到一个 case,值得分享一下. 现象就是一个 update 操作,在 mysql 客户端中执行提示 warning,但在 java 程序中执行却又报错. 问题重现 mysql> crea ...

  9. PbRL | Preference Transformer:反正感觉 transformer 很强大

    论文题目:Preference Transformer: Modeling Human Preferences using Transformers for RL,ICLR 2023,5 6 6 8, ...

  10. 010 editor 文件指纹分析

    1.010 Editor  介绍 16进制编辑器,支持模板和脚本操作,010编辑器支持编辑的文件类型 https://www.sweetscape.com/010editor/repository/t ...