题目

将互不相同的 \(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. win32 - WriteConsoleA 的使用

    #include <Windows.h> #include <stdio.h> #pragma warning(disable:4996) void PasswordCheck ...

  2. ASP.NET Core MVC应用模型的构建[3]: Controller的收集

    从编程的角度来看,一个MVC应用是由一系列Controller类型构建而成的,所以对于一个代表应用模型的ApplicationModel对象来说,它的核心就是Controllers属性返回的一组Con ...

  3. 【Azure 应用服务】更便捷的方式抓取Azure App Service for Windows的网络包

    问题描述 在之前的一篇博文中,介绍了在App Service中抓取网络日志: 抓取Windows的网络包:[应用服务 App Service]App Service中抓取网络日志 抓取Linux的网络 ...

  4. 论文《Attention is all you need》阅读笔记

    Attention is all you need Transformer模型 Model Architecture Transformer结构上和传统的翻译模型相同,拥有encoder-decode ...

  5. SpringCloud 网关组件Gateway

    官网文档: https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/ 1. 概述 1.1 什么是网关 ...

  6. Sliver C2通关渗透攻击红队内网域靶场2.0

    准备 2012 server 第一台机器开机后,要在C:\Oracle\Middleware\Oracle_Home\user_projects\domains\base_domain​手动运行下 s ...

  7. 文心一言 VS 讯飞星火 VS chatgpt (210)-- 算法导论16.1 1题

    一.根据递归式(16.2)为活动选择问题设计一个动态规划算法.算法应该按前文定义计算最大兼容活动集的大小 c[i,j]并生成最大集本身.假定输入的活动已按公式(16.1)排好序.比较你的算法和GREE ...

  8. APP限制录屏怎么办?如何绕过APP录屏限制和截图限制-支持安卓和IOS

    简要:互联网越来越发达,衍生了很多形形色色的app,商家为了防止app资源被传播,因此在用户截取屏幕操作或者录屏操作时会警告用户并前会禁止用户的这一操作行为. 那么有没有办法解决呢?有人说可以用投屏. ...

  9. 解决 Steam for Linux 部分 Valve 游戏中文显示问题/军团要塞2的字体显示问题

    解决 Steam for Linux 部分 Valve 游戏中文显示问题 发表于 Apr 7th 2019 | 分类于 Keep Digging Steam for Linux 上有许多好玩的免费游戏 ...

  10. 脑电测量ADS1299芯片调试总结

    问题一:读出来ID不对? 笔者经过查阅官网资料和测试,发现这个一般是上电或者启动次序不对引起的. 特别是上电次序不同会导致这类问题. 问题二:内部时钟和外部时钟的选择是什么? 就拿内部时钟来说吧,首先 ...