题目大意

将 \(N\) 个互不相同的整数 \(A_1 , A_2 , ⋯ , A_N\) 任意排列成 \(B_1 , B_2 , ⋯ , B_N\) 。

要求 \(∑^{N−1}_{i=1} |B_{i+1} − B_i | ≤ L\)

计数方案数 \(N ≤ 100\ L ≤ 1000\)。

解题思路

是一个比较经典的 DP 方式。但是大家都不屑于讲清楚这个转移,所以只好从网上找一篇记录一下。

首先考虑将贡献差分一下,假设在 \(a_i\) 放下去前一刻有 \(i\) 个空位,则进行放置这个操作的贡献就是 \((a_i-a_{i-1})\times i\)。

那么考虑从小到大放置,每一时刻就会是一些连续段。

设 \(f[i][j][s][d]\) 表示已经放置前 \(i\) 个数,分成 \(j\) 段,目前贡献为 \(s\),有 \(d\) 个边界已确定的方案数。

注意这个 DP 中我们只需要保证每段是否在边界以及相邻两段之间有空位即可,不关心每段的实际位置。

从转移来感受一下上面这句话:

  1. 新建一段 (这一段可以放在边界除外的任意 \(j+1\) 个空隙内);
  2. 合并两段;
  3. 放在其中一段的其中一端;
  4. 新建一段并钦定其为边界;
  5. 接在最左段 (不能为边界) 的左端并钦定为边界,或接在最右段 (不能为边界) 的最右端并钦定为边界;

转移的时候注意判合法。

#include <set>
#include <map>
#include <queue>
#include <bitset>
#include <vector>
#include <math.h>
#include <ctype.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std; const int N(105), M(1005), mod(1e9 + 7); int n, L, a[N];
int b[N];
int f[N][N][M][3]; inline void read(int &x){
x = 0; int f = 1, c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)) x = x * 10 + c - 48, c = getchar();
x *= f;
} inline void MOD(int &x){ x = x + ((x >> 31) & mod); } int main(){
read(n), read(L);
for(int i(1); i <= n; ++i) read(a[i]);
if(n == 1) return puts("1"), 0;
sort(a + 1, a + n + 1);
for(int i(2); i <= n; ++i) b[i] = a[i] - a[i - 1];
f[0][0][0][0] = 1;
for(int i(0); i < n; ++i)
for(int j(0); j <= i; ++j)
for(int s(0); s <= L; ++s)
for(int d(0); d <= 2; ++d){
if(!f[i][j][s][d]) continue;
int more = b[i + 1] * (j * 2 - d); if(s + more > L) continue;
MOD(f[i + 1][j + 1][s + more][d] += 1LL * f[i][j][s][d] * (j + 1 - d) % mod - mod);
if(j) MOD(f[i + 1][j - 1][s + more][d] += 1LL * f[i][j][s][d] * (j - 1) % mod - mod);
MOD(f[i + 1][j][s + more][d] += 1LL * f[i][j][s][d] * (2 * j - d) % mod - mod);
if(d == 2) continue;
MOD(f[i + 1][j + 1][s + more][d + 1] += 1LL * f[i][j][s][d] * (2 - d) % mod - mod);
if(j) MOD(f[i + 1][j][s + more][d + 1] += 1LL * f[i][j][s][d] * (2 - d) % mod - mod);
}
int ans = 0;
for(int i(0); i <= L; ++i) MOD(ans += f[n][1][i][2] - mod);
printf("%d\n", ans);
return 0;
}
/* Hemerocallis */

[题解] [LOJ2743]「JOI Open 2016」摩天大楼的更多相关文章

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

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

  2. 【题解】LOJ2759. 「JOI 2014 Final」飞天鼠(最短路)

    [题解]LOJ2759. 「JOI 2014 Final」飞天鼠(最短路) 考虑最终答案的构成,一定是由很多飞行+一些上升+一些下降构成. 由于在任何一个点上升或者下降代价是一样的,所以: 对于上升操 ...

  3. 「JOI 2017 Final」JOIOI 王国

    「JOI 2017 Final」JOIOI 王国 题目描述 题目译自 JOI 2017 Final T3「 JOIOI 王国 / The Kingdom of JOIOI」 JOIOI 王国是一个 H ...

  4. 「JOI 2015 Final」分蛋糕 2

    「JOI 2015 Final」分蛋糕 2 题解 这道题让我想起了新年趣事之红包这道DP题,这道题和那道题推出来之后的做法是一样的. 我们可以定义dp[i][len][1] 表示从第i块逆时针数len ...

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

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

  6. 【LOJ】#3014. 「JOI 2019 Final」独特的城市(长链剖分)

    LOJ#3014. 「JOI 2019 Final」独特的城市(长链剖分) 显然我们画一条直径,容易发现被统计的只可能是直径某个距离较远的端点到这个点的路径上的值 用一个栈统计可以被统计的点,然后我们 ...

  7. 「JOI 2014 Final」飞天鼠

    「JOI 2014 Final」飞天鼠 显然向上爬是没有必要的,除非会下降到地面以下,才提高到刚好为0. 到达一个点有两种情况:到达高度为0和不为0. 对于高度不为0的情况,显然花费的时间越少高度越高 ...

  8. 「JOI 2015 Final」城墙

    「JOI 2015 Final」城墙 复杂度默认\(m=n\) 暴力 对于点\((i,j)\),记录\(ld[i][j]=min(向下延伸的长度,向右延伸的长度)\),\(rd[i][j]=min(向 ...

  9. 「JOI 2015 Final」舞会

    「JOI 2015 Final」舞会 略微思考一下即可知该过程可以化为一棵树.(3个贵族中选择1个,即新建一个节点连向这3个贵族). 该树的结点个数为\(2n\). 考虑二分答案mid. 判定的是公主 ...

随机推荐

  1. Thymeleaf+Spring使用自己的工具类

    第一种.提供思路,继承SpringStandardDialect,重写getExpressionObjectFactory方法,设置expressionObjectFactory的实际对象,并在Tem ...

  2. 1.0缓存:Login.aspx?

    所有的manifest资源配置文件以CACHE MANIFEST声明开头. #(哈希标签)有助于提供缓存文件的版本. CACHE命令指定哪些文件需要被缓存. manifest资源配置文件的内容类型应是 ...

  3. java中的VO、PO、BO、DAO、POJO

     针对java工程里的各种带O的对象,进行分析,了解各自的作用. PO: persistent object,持久对象.与数据库里表字段一一对应.PO是一些属性,以及set和get方法组成.一般情况下 ...

  4. 分享一波dubbo mybatis plus百度云链接

    https://pan.baidu.com/s/1VtfoVJwan-XPvmQfBIKMhA

  5. springboot-mail发邮件,不需要邮件服务器

    很简单 步骤走起-> 1.需要一个邮箱账号,我以163邮箱为例,先开启第三方服务后获得密码,后面用来邮箱登录 2.加入mail 依赖 3.properties配置账号和第三方服务密码(不是邮箱密 ...

  6. 顺利通过EMC实验(20)

  7. 一个看一次就永远不会忘的windows环境开发小技巧

    前言:本人前端开发,在日常开发中需要打开多个窗口进行开发,如:本地服务窗口,ide工具,设计图,prd文档,浏览器,浏览器调试工具: 如此多的窗口同时打开并且时常需要查看的情况下,遗憾的是,即使我是双 ...

  8. HTML2Canvas使用总结

    1:指定要生成的DOM元素id 2: 某些图片动态赋值src的url或者base64可能不会被立即渲染:可以设置一个定时器解决 3:可以调用次方法得到的canvas元素转一下格式 png/jpg 4: ...

  9. 使用pyinstaller库打包文件

    1.pyinstaller的安装 先win+r打开cmd,安装具体命令如下: pip3 install pyinstaller  2.使用pyinstaller库打包文件 假设Python源文件LPR ...

  10. URLDNS反序列化链学习

    URLDNS URLDNS跟CommonsCollections比起来真是眉清目秀,该链主要用于验证漏洞,并不能执行命令,优点就是不依赖任何包. 1.利用链 * Gadget Chain: * Has ...