题目大意

将 \(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. CopyOnWriteArrayList 可以用于什么应用场景?

    CopyOnWriteArrayList(免锁容器)的好处之一是当多个迭代器同时遍历和修改这 个列表时,不会抛出 ConcurrentModificationException.在 CopyOnWri ...

  2. jenkins-learning

    常规的打包方式: 提交代码 拉去代码并打包:war包和jar包 上传到服务器 关闭当前程序 启动新的jar包 查看新的jar包是否起作用 jenkins自动化流程: CI(Continuous int ...

  3. SpringCloud个人笔记-03-Config初体验

    sb-cloud-config 配置中心 <?xml version="1.0" encoding="UTF-8"?> <project xm ...

  4. jsp技术之隐藏域

    隐藏域 hidden:隐藏域属性,不显示到页面上,但是会提交的表单项 注意:表单中增加了一个隐藏域,是用户的id.稍后修改联系人信息,提交表单时需要使用到 <!-- hidden:隐藏域,不显示 ...

  5. 【Web Audio API】 — 那些年的 web audio

    转 TAT.Jdo:[Web Audio API] - 那些年的 web audio 这主题主要是早期对 web audio api的一些尝试,这里整理一下以便以后翻阅,如有错误,诚请指正. 在这之前 ...

  6. css样式权重优先级,css样式优先级

    原文:http://www.bkjia.com/Javascri... 样式选择器权重优先级: important > 内嵌样式 > ID > 类 > 标签 | 伪类 | 属性 ...

  7. 国际化相对时间格式化API:Intl.RelativeTimeFormat

    原文:The Intl.RelativeTimeFormat API 作者:Mathias Bynens(@mathias) 现代 Web 应用程序通常使用"昨天","4 ...

  8. 【每日日报】第三十八天---java与时间相关

    1 今天看了网上的课程 学习了java的关于时间的代码 获取时间 import java.util.Date; public class DateDemo { public static void m ...

  9. JS判断数组中的对象的每一个值不能为空

    方法一:使用every()函数,此函数不怎么常用,想要了解更多请自查 //表格 evaluateData为表格的数据 <el-table id="out-table3" :d ...

  10. 数组 indexOf()

    众所周知,indexOf()这个方法经常出现在字符串的使用中,也许是用来寻找字符串中某一字符在字符串中的位置,或者也可以用来寻找字符串中重复出现的字符有哪些.对于刚接触 JS 的我们来说,在对数组的操 ...