决策单调性Ⅰ:四边形不等式(bzoj 1563: [NOI2009]诗人小G)
题目描述:
给出n个数字和常数L,你可以任意合并相邻的两个数字a[x]和a[x+1],并得出一个新的数a[x]+a[x+1]+1,一通合并后得到一个有若干个数的序列,这个序列的不协调值为∑|(a[i]-L)^p|,求最小不协调值
例如L=7,初始4个数分别为3 3 1 5,那么肯定是将前两个数合并,后两个数合并得出7 7,这时不协调值一定为0
n<=100000,L<=300000,P<=10
设dp[i]为前i个数的最小不协调度,len[]为第i个数有
复杂度O(n²P),肯定过不去
当P=2时,设sum[]为len[]的前缀和,若k点比j点更优,且j<k<i,那么有
维护一个下凸包,这样当P=2时,斜率优化复杂度O(n)
斜率优化可见:决策单调性Ⅱ:斜率优化
这就是题目 1010: [HNOI2008]玩具装箱toy 的题解
可这题P不一定等于2,还是过不去
不过以上说明了这个DP可能是有决策单调性的
那么先说:什么是决策单调性?
先提一个词:1D/1D动态规划,指的是状态为O(n),每一个状态决策都需要O(n)遍历前面所有决策才能得出的动态规划,直接求解的复杂度是O(n²),但很多情况下都可以通过一系列手段优化成O(nlogn)或者O(n)(例如平行四边形优化 和斜率优化)
1D/1D动态规划经典模型:
假设j点是当前i点的最优决策,那么决策单调性就是指:
对于所有的x>i,最优决策p(x)一定都大于j
也可这么理解:假设a是dp[x]的最优决策,b是dp[x-1]点的最优决策,a>b,那么对于所有的p>x,从a点转移一定比b点更优,对于所有的p<x-1,从b点转移一定比a点更优
还可以这么理解:每个决策点能决策的区间一定是连续的一段,并且随着决策点的右移,这个区间也在不断右移
充要条件:
具体证明比较复杂,而且题目不同证明应该也会有不同,这里就略
贴一篇证明https://www.byvoid.com/zhs/blog/noi-2009-poet
一般题目都能看出来,没必要证,等你证完别人都AC了
那么知道了决策单调性,怎么搞?
通过上面蓝色字体,可以这样思考:对于当前决策点,它能影响的区间是哪些?
举个例子假设n=30,一步一步来:
先搞出dp[1],那么所有后续状态dp[x]的目前最优决策一定都是1,决策表如下:
111111111111111111111111111111
然后再算出dp[2],由于决策单调性,决策表一定会变成这样:
111111111122222222222222222
再算出dp[3]:111111111122222233333333333
再算出dp[4]:111111111122222244444444444
再算出dp[5]:111111111122222244555555555
……
那么可以看出,每个决策在决策表中一定会有且只有一个转折点
理论上只要知道这个转折点就可以
具体过程:
用一个栈来维护,里面保存每一个决策的起始位置和终点位置,显然这些位置是首尾相接的
每出现一个新决策,从后往前扫描栈,这个时候有两种情况:
①如果在某个老决策起点处新决策更好,那么把这个老决策直接弹出栈(扔掉),用新决策代替之,就如同上面例子中算出dp[4]之后,决策3被完全抛弃
②如果在某个老决策起点处还是老决策更好,那么转折点必定在这个老决策区间内,二分查找并插入新决策
复杂度分析:每个决策出栈进栈1次,每次二分,所以O(nlogn)
回到这题,看DP式子
这不就是
的模型题么,其中w[i, j]就是后面那一长串
就用上述方法就ok了
1563: [NOI2009]诗人小G
Time Limit: 100 Sec Memory Limit: 64 MB
Submit: 2736 Solved: 885
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
Sample Output
这题就是上面那个例子,代码里有注释
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define LL long long
#define Inf 1e18
#define LD long double
int n, L, p, top, st[100005], k[100005], a[100005], sum[100005];
LD dp[100005];
LD Pow(int x, int y)
{int i;LD ans = 1;for(i=1;i<=y;i++)ans = ans*x;if(ans<0)ans = -ans;return ans;
}
LD Calc(int j, int i)
{return dp[j]+Pow(sum[i]-sum[j]+i-j-1-L, p);
}
int Find(int x)
{int l, r, m;l = 1, r = top;while(l<r){m = (l+r+1)/2;if(x>=k[st[m]])l = m;elser = m-1;}return r;
}
int Find_pos(int i, int x)
{int l, r, m;l = max(i+1, k[x]+1), r = n+1;while(l<r){m = (l+r)/2;if(Calc(i, m)<Calc(x, m))r = m;elsel = m+1;}return r;
}
int main(void)
{char str[35];int i, T, x;scanf("%d", &T);while(T--){scanf("%d%d%d", &n, &L, &p);for(i=1;i<=n;i++){scanf("%s", str+1);a[i] = strlen(str+1);sum[i] = sum[i-1]+a[i];}top = 0, k[0] = 0;st[++top] = 0;for(i=1;i<=n;i++){x = st[Find(i)]; //找到i点所在区间是哪个最优决策点的区间dp[i] = Calc(x, i); //因为是最优决策点,直接计算while(k[st[top]]>i && Calc(i, k[st[top]])<Calc(st[top], k[st[top]])) //对于当前新决策,从后往前扫描栈top--; //如果在某个老决策起点处新决策更好,那么直接把这个老决策直接弹出栈(扔掉),用新决策代替之x = Find_pos(i, st[top]); //如果在某个老决策起点处还是老决策更好,那么转折点必定在这个老决策区间内,二分查找并插入新决策if(x==n+1) //↑↑这里偷个懒,直接扫老决策起点往后的整个数组而不是扫老决策区间continue;k[i] = x;st[++top] = i; //插入新决策}/*for(i=1;i<=n;i++){dp[i] = 7*Inf;for(j=0;j<=i-1;j++)dp[i] = min(dp[i], Calc(j, i));}*/if(dp[n]>Inf)printf("Too hard to arrange\n--------------------\n");elseprintf("%lld\n--------------------\n", (LL)dp[n]);}return 0;
}
/*
1
4 9 2
brysj,
hhrhl.
yqqlm,
gsycl.
*/
决策单调性Ⅰ:四边形不等式(bzoj 1563: [NOI2009]诗人小G)相关推荐
- P1912 [NOI2009]诗人小G
P1912 [NOI2009]诗人小G 思路: 平行四边形不等式优化dp 因为f(j, i) = abs(sum[i]-sum[j]+i-j-1-l)^p 满足平行四边形不等式 j < i f( ...
- NOI2009 诗人小G
题目 小G是一个出色的诗人,经常作诗自娱自乐.但是,他一直被一件事情所困扰,那就是诗的排版问题. 一首诗包含了若干个句子,对于一些连续的短句,可以将它们用空格隔开并放在一行中,注意一行中可以放的句子数 ...
- [BZOJ1563][NOI2009]诗人小G[决策单调性优化]
int T, n, m, l, p, pre[MAXN], q[MAXN], h, t, b[MAXN];//b[i]表示决策点是i的最后一个位置 llf dp[MAXN]; char s1[35]; ...
- BZOJ1563:[NOI2009]诗人小G(决策单调性DP)
Description Input Output 对于每组数据,若最小的不协调度不超过1018,则第一行一个数表示不协调度若最小的不协调度超过1018,则输出"Too hard to arr ...
- 【NOI 2009】诗人小G
[NOI 2009]诗人小G Problem Description 小 \(G\) 是一个出色的诗人,经常作诗自娱自乐.但是,他一直被一件事情所困扰,那就是诗的排版问题. 一首诗包含了若干个句子,对 ...
- P1912-[NOI2009]诗人小G【四边形不等式,单调队列】
正题 题目链接:https://www.luogu.com.cn/problem/P1912 题目大意 给出nnn个字符串,把这些字符串依次用空格(算一个长度)连接分成若干段,若一段长度为xxx,那么 ...
- 洛谷P1912:诗人小G(二分栈、决策单调性)
二分栈,就是通过二分维护的栈 (逃) 解析 本题的决策单调性可以说是显然 但是本题是同维度(其实只有一维)自左向右转移,分治的写法是不能奏效的 所以我们使用决策点调性的另一种实现方法:二分栈 具体来说 ...
- 一个诗人的一生——诗人小G的人生
看到群里有人说周末作文是以一个诗人的一生为题写作文-于是就突发脑洞写了这么个东西. 哇发出来好羞耻啊(x 诗与人生 某一天,在某一个地方,小G诞生了. 小G原本是有自己的名字的,但是在某一天之后,他就 ...
- 【NOI2009】诗人小G【决策单调性dp】
传送门 设句子加上空格长度前缀和为sss 转移方程为 fi=min1≤j<i{fj+∣si−sj−L−1∣P}f_i=\min_{1\leq j<i}\{f_j+|s_i-s_j-L-1 ...
最新文章
- linux下如何更新镜像源(ubuntu 10.04 为例),Ubuntu 10.04 更新源补充
- 「LibreOJ β Round #2」计算几何瞎暴力
- 代理模式在Spring 源码中的应用
- 软件培训技术选哪个?
- mysql在线备份恢复--Xtrabackup
- 从△走进OO,走进策略模式
- ICCV2013 录用论文(目标跟踪相关部分)
- Android百度浏览器深色模式,深色模式适配指南
- Verilog 练习 简单状态机代码设计(三角波发生器)
- python抓取网页图片教程_Python实现简单网页图片抓取完整代码实例
- 前台获取model中的值,json数据,json字符串,双引号变为 ‘ quto;‘
- 二级计算机合格,计算机二级考试合格的分数线
- 项目管理之-WBS(Work Breakdown Structure, 工作分解结构)
- OpenCV读取图片
- android仿微信录制短视频并播放视频
- Spring配置解析之Component-scan解析
- 西电数据挖掘实验3——复杂网络社团检测
- 【Ajax】第一课 Ajax访问Servlet解析Json格式
- idea如何配置或者创建mybatis的xml文件 idea如何配置或者创建mybatis的配置文件
- MySQL数据存储空间
热门文章
- python中文视频教程-中谷教育python中文视频教程(python视频教程) 完整版
- vb还是python强大-Python可以代替vb吗
- python怎么读取txt文件-Python笔记(读取txt文件中的数据)
- 语音识别中的CTC算法的基本原理解释
- element ui 点击修改开启停用按钮状态
- css3 first letter,::first-letter
- vue cli3 一键 build 区分测试环境和正式环境
- 日志分析里面的max是什么_mysql慢日志文件分析处理
- 【java笔记】线程池的介绍和使用
- cocos2d-x3.4 android重新编译,cocos2d-x 4.0 Spine 3.8编译环境配置(高级篇)