HYSBZ 1010 玩具装箱toy (决策单调DP)
题意:
有n个玩具,要将它们分为若干组,玩具长度C可能不同。给出n个玩具的摆放顺序,连续的任意多个玩具都可以成为一组。区间[i,j]成为一组的费用是cost=(j-i+Sigma(Ck)-L)2且i<=k<=j。给定n和L和每个玩具的长度,问分组后费用总和是多少? (n<=5*104)。
思路:
转移方程:dp[i]=min( dp[j]+(sum[i]-sum[j]+i-j+1-L)2 )。sum[i]表示前i件玩具长度的总和,0<j<i,(i-j+1)表示与i同组的玩具个数。
根据方程是可以推出这题是满足决策单调性的。以下是抄来的证明,稍微修改:
令f[i]=sum[i]+i, c=1+L,则dp[i]=min( dp[j]+(f[i]-f[j]-c)2 )
1.证明决策单调性
假设在状态i处的k决策优于j决策,且j<k,那么 dp[k]+(f[i]-f[k]-c)2<=dp[j]+(f[i]-dp[j]-c)2。
而对于i后面的某个状态t,设f[t]=f[i]+v,先不管v是多少。
要证明:dp[k]+(f[t]-f[k]-c)2<=dp[j]+(f[t]-f[j]-c)2
只要证(将f[t]=f[i]+v代入):dp[k]+(f[i]+v-f[k]-c)2<=dp[j]+(f[i]+v-f[j]-c)2
只要证dp[k]+(f[i]-f[k]-c)2+2v*(f[i]-f[k]-c)+v2 <= dp[j]+(f[i]-f[j]-c)2+2v*(f[i]-f[j]-c)+v2。
由于假设,所以只要证: 2v*(f[i]-f[k]-c)<=2v*(f[i]-f[j]-c)。
即证:f[k]>=f[j](显然)
证明完毕
思路很明确,一直卡在二分上面,噗。
用一个队列来维护这些区间段,由于区间段必定是连在一起的,所以只需要记录左端点L以及更新这个区间的决策k。如果队列为空,则后面全部由i来更新得到,若非空,那么判断队尾的L,是否由i来更新会更优,若是,则pop掉队尾,继续同样的动作,直到队列为空或者i作为决策不如队尾的L更好,那么i可以更新的就是[L,n]之中的尾部区间[r,n],而r可以用二分查找的方式。细节上很容易写挫,比如i决策可能完全都可以用武之地,不用二分去找了,否则会错;二分时必定要保证r由i来更新更佳,且有可能会出现等于的情况。复杂度O(nlogn),斜率优化等再写。
//#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <deque>
#include <map>
#include <algorithm>
#include <vector>
#include <iostream>
#define pii pair<int,int>
#define back que[rear-1]
#define INF 0x7f7f7f7f
#define LL long long
#define ULL unsigned long long
using namespace std;
const double PI = acos(-1.0);
const int N=; LL len[N], dp[N], L;
int q[N], d[N], n, l, r; //区间以及决策
LL cost(int j,int i) //用j来更新i的费用
{
return dp[j]+(len[i]-len[j]-L)*(len[i]-len[j]-L);
} int find(int i,int k,int st)
{
int ll=st, rr=n;
while(ll<rr)
{
int mid=rr-(rr-ll+)/;
if( cost(i,mid)<cost(k,mid)) rr=mid;
else ll=mid+;
}
return rr;
}
LL cal()
{
l=r=;
d[]=;q[]=; //初始时,0可以更新[1,n]
for(int i=; i<=n; i++)
{
dp[i]=cost(d[l], q[l]++); //q[l]永远等于i
if( l<r && q[l]==q[l+] ) l++; while( l<=r && cost(i,q[r])<cost(d[r],q[r]) ) r--;
if(l>r) //只能用i来更新
{
q[++r]=i+;
d[r]=i;
}
else if( cost(i,n)<cost(d[r],n))
{
int tmp=find(i, d[r], q[r]);
q[++r]=tmp;
d[r]=i;
}
}
return dp[n];
} int main()
{
//freopen("input.txt","r",stdin);
while(~scanf("%d%lld",&n,&L))
{
L++;len[]=;
for(int i=; i<=n; i++)
{
scanf("%lld",&len[i]);
len[i]+=len[i-];
}
for(int i=; i<=n; i++) len[i]+=i;
printf("%lld\n", cal() );
}
return ;
}
AC代码
HYSBZ 1010 玩具装箱toy (决策单调DP)的更多相关文章
- BZOJ 1010: 玩具装箱toy (斜率优化dp)
Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1... ...
- BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化DP
1010: [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...
- 『玩具装箱TOY 斜率优化DP』
玩具装箱TOY(HNOI2008) Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊 ...
- bzoj1010[HNOI2008]玩具装箱toy 斜率优化dp
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 11893 Solved: 5061[Submit][S ...
- BZOJ 1010 玩具装箱toy(四边形不等式优化DP)(HNOI 2008)
Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1... ...
- BZOJ 1010 玩具装箱toy(斜率优化DP)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1010 题目大意:P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他 ...
- 洛谷P3195 [HNOI2008]玩具装箱TOY(单调队列优化DP)
题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具, ...
- bzoj 1010 玩具装箱toy -斜率优化
P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具,第i件玩具 ...
- P3195 [HNOI2008]玩具装箱TOY 斜率优化dp
传送门:https://www.luogu.org/problem/P3195 题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任 ...
随机推荐
- AngularJs(Part 2)
I am still tired to translate these into Chinese. but who cares? i write these posts just for myself ...
- db2 command line notes
db2ilist - list instances db2 attach to <instance> user <username> using <password> ...
- 二维数组是二级指针pointer to pointer!
二维数组居然是个类似于二级指针(pointer to pointer)的东西,十分震惊! #include <stdio.h> int main() { ][]={{,,,},{,,,}, ...
- 【网络爬虫】【python】网络爬虫(五):scrapy爬虫初探——爬取网页及选择器
在上一篇文章的末尾,我们创建了一个scrapy框架的爬虫项目test,现在来运行下一个简单的爬虫,看看scrapy爬取的过程是怎样的. 一.爬虫类编写(spider.py) from scrapy.s ...
- 51Nod - 1154 回文串划分(最少回文串dp)
回文串划分 有一个字符串S,求S最少可以被划分为多少个回文串. 例如:abbaabaa,有多种划分方式. a|bb|aabaa - 3 个回文串 a|bb|a|aba|a - 5 个回文串 a|b ...
- js 实现发布订阅模式
/* Pubsub */ function Pubsub(){ //存放事件和对应的处理方法 this.handles = {}; } Pubsub.prototype = { //传入事件类型typ ...
- 《深入理解Java虚拟机》笔记01 -- 运行时数据区
运行时数据区示意图 1. 程序计数器 占用一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器.主要用来记录线程执行到哪条语句了,分支.循环.跳转.异常处理.线程恢复等功能都需要依赖这个 ...
- uoj#388. 【UNR #3】配对树(线段树合并)
传送门 先考虑一个贪心,对于一条边来说,如果当前这个序列中在它的子树中的元素个数为奇数个,那么这条边就会被一组匹配经过,否则就不会 考虑反证法,如果在这条边两边的元素个数都是偶数,那么至少有两组匹配经 ...
- jQuery EasyUI/TopJUI创建文本验证框(不写js,纯HTML实现!!!)
jQuery EasyUI/TopJUI创建文本验证框(不写js,纯HTML实现!!!) validatebox(验证框)的设计目的是为了验证输入的表单字段是否有效.如果用户输入了无效的值,它将会更改 ...
- node.js安装与配置
node.js是一个基于Chrome V8引擎的javascrit运行环境. node.js使用了一个事件驱动.非阻塞式I/O的模型,使其轻量又高级. node.js的包管理器npm,是全球最大的开源 ...