[题解] [LOJ2743]「JOI Open 2016」摩天大楼
题目大意
将 \(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 中我们只需要保证每段是否在边界以及相邻两段之间有空位即可,不关心每段的实际位置。
从转移来感受一下上面这句话:
- 新建一段 (这一段可以放在边界除外的任意 \(j+1\) 个空隙内);
- 合并两段;
- 放在其中一段的其中一端;
- 新建一段并钦定其为边界;
- 接在最左段 (不能为边界) 的左端并钦定为边界,或接在最右段 (不能为边界) 的最右端并钦定为边界;
转移的时候注意判合法。
#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」摩天大楼的更多相关文章
- [LOJ#2743][DP]「JOI Open 2016」摩天大楼
题目传送门 DP 经典题 考虑从小到大把数加入排列内 如下图(\(A\) 已经经过排序): 我们考虑如上,在 \(i\) ( \(A_i\) )不断增大的过程中,维护上面直线 \(y=A_i\) 之下 ...
- 【题解】LOJ2759. 「JOI 2014 Final」飞天鼠(最短路)
[题解]LOJ2759. 「JOI 2014 Final」飞天鼠(最短路) 考虑最终答案的构成,一定是由很多飞行+一些上升+一些下降构成. 由于在任何一个点上升或者下降代价是一样的,所以: 对于上升操 ...
- 「JOI 2017 Final」JOIOI 王国
「JOI 2017 Final」JOIOI 王国 题目描述 题目译自 JOI 2017 Final T3「 JOIOI 王国 / The Kingdom of JOIOI」 JOIOI 王国是一个 H ...
- 「JOI 2015 Final」分蛋糕 2
「JOI 2015 Final」分蛋糕 2 题解 这道题让我想起了新年趣事之红包这道DP题,这道题和那道题推出来之后的做法是一样的. 我们可以定义dp[i][len][1] 表示从第i块逆时针数len ...
- LOJ#2351. 「JOI 2018 Final」毒蛇越狱
LOJ#2351. 「JOI 2018 Final」毒蛇越狱 https://loj.ac/problem/2351 分析: 首先有\(2^{|?|}\)的暴力非常好做. 观察到\(min(|1|,| ...
- 【LOJ】#3014. 「JOI 2019 Final」独特的城市(长链剖分)
LOJ#3014. 「JOI 2019 Final」独特的城市(长链剖分) 显然我们画一条直径,容易发现被统计的只可能是直径某个距离较远的端点到这个点的路径上的值 用一个栈统计可以被统计的点,然后我们 ...
- 「JOI 2014 Final」飞天鼠
「JOI 2014 Final」飞天鼠 显然向上爬是没有必要的,除非会下降到地面以下,才提高到刚好为0. 到达一个点有两种情况:到达高度为0和不为0. 对于高度不为0的情况,显然花费的时间越少高度越高 ...
- 「JOI 2015 Final」城墙
「JOI 2015 Final」城墙 复杂度默认\(m=n\) 暴力 对于点\((i,j)\),记录\(ld[i][j]=min(向下延伸的长度,向右延伸的长度)\),\(rd[i][j]=min(向 ...
- 「JOI 2015 Final」舞会
「JOI 2015 Final」舞会 略微思考一下即可知该过程可以化为一棵树.(3个贵族中选择1个,即新建一个节点连向这3个贵族). 该树的结点个数为\(2n\). 考虑二分答案mid. 判定的是公主 ...
随机推荐
- JSP有哪些动作?分别是什么?
外JSP共有以下7种基本动作 jsp:include:在页面被请求的时候引入一个文件. jsp:useBean:寻找或者实例化一个JavaBean. jsp:setProperty:设置JavaBea ...
- 为什么要用 Spring Boot?
Spring Boot 优点非常多,如:独立运行简化配置自动配置无代码生成和XML配置应用监控上手容易Spring Boot 集这么多优点于一身,还有理由不使用它呢?
- phpstorm 快捷生成函数
在函数上一行键入 /** /** * @param $a * @param $b * @return mixed */ function abc($a, $b) { $c = $a + $b; ret ...
- 记一次 Nuxt 3 在 Windows 下的打包问题
0. 背景 之前用 Nuxt 3 写了公司的官网,包括了样式.字体图标.图片.视频等,其中样式和字体图标放在了 assets/styles 和 assets/fonts 目录下,而图片和视频则放在了 ...
- 无人驾驶—高精地图和V2X
高精地图将厘米级的静态信息传传递给无人车V2X将路况上的动态信息传递给无人车 高精地图的作用 高精地图与传统地图的对比 高精地图与定位的关系 上图左侧是感知到的区域,右侧是高精地图,之后进行拼接获得车 ...
- ES6-11学习笔记--异步迭代
ES9提供异步迭代: for await of Symbol.asyncIterator function getPromise(time) { return new Promise((resol ...
- python爬虫---爬取网易云音乐
代码: import requests from lxml import etree text = requests.get("https://music.163.com/discover/ ...
- APK安装流程概述
pre { background: none left top repeat scroll rgba(0, 0, 0, 0); border: 1px solid rgba(0, 0, 0, 1); ...
- CCF201409-2 画图
问题描述 在一个定义了直角坐标系的纸上,画一个(x1,y1)到(x2,y2)的矩形指将横坐标范围从x1到x2,纵坐标范围从y1到y2之间的区域涂上颜色. 下图给出了一个画了两个矩形的例子.第一个矩形是 ...
- MySQL数据库设置编码格式和时区
MySQL数据库设置编码格式和时区 MySQL5版本: url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8 MySQL6版本及以上 ...