BZOJ 1010 玩具装箱toy(四边形不等式优化DP)(HNOI 2008)
Description
P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京。他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中。P教授有编号为1...N的N件玩具,第i件玩具经过压缩后变成一维长度为Ci.为了方便整理,P教授要求在一个一维容器中的玩具编号是连续的。同时如果一个一维容器中有多个玩具,那么两件玩具之间要加入一个单位长度的填充物,形式地说如果将第i件玩具到第j个玩具放到一个容器中,那么容器的长度将为 x=j-i+Sigma(Ck) i<=K<=j 制作容器的费用与容器的长度有关,根据教授研究,如果容器长度为x,其制作费用为(X-L)^2.其中L是一个常量。P教授不关心容器的数目,他可以制作出任意长度的容器,甚至超过L。但他希望费用最小.
Input
第一行输入两个整数N,L.接下来N行输入Ci.1<=N<=50000,1<=L,Ci<=10^7
Output
输出最小费用
题目大意:略。
思路:由题意,令w(i, j) = (j - i + sum{c[i..j]} - L)^2
按照黑书(《算法艺术与信息学竞赛》)中的说法,要满足四边形不等式,只需要:
①j 不变时,f(i) = w(i, j + 1) - w(i, j)单调递减。
②i 不变时,f(j) = w(i + 1, j) - w(i, j)单调递减。
当且仅当①②都成立时,w符合四边形不等式(这题里面这个很好验证,就不写了)。
此时决策单调(虽然我不知道为什么……),解法可以参照《1D/1D动态规划优化初步》,我的解法就是参照这个写的。
另外,还有斜率优化的写法(虽然我不会),可以参照http://blog.sina.com.cn/s/blog_5f5353cc0100jx41.html
但是在我跑这样一组数据时(随机生成的):
50 5691358
8467214 9692279 8158876 7023812 4301767 4313397 2378849 778746 2288987 3052905 7228328 6855441 4280591 1058424 889808 530342 9432467 761829 3969985 3193649 8070892 711348 5821773 3062537 6891494 5695393 3803579 6418375 1578074 2363659 6477728 533247 6025318 8151154 2442635 1113076 506233 3594564 8277434 1584861 2276145 4442621 7105356 8729441 7283702 1250929 5133264 9233541 5267813 2889179
答案与我的程序跑出的结果136165306871056不一样。稍微目测了一下,上面斜率优化的代码越界了(我不知道怎么改了……)
w(i, j)的极限可高达(50000 - 1 + 50000 * 10^7 - 0)^2,超出了64位整数的范围(虽说似乎没有这样的大数据)。
本人的代码在修改后应该是不会存在越界的问题的(避免了两个较大数的乘法,可以参照代码里面的check函数)。
PS:答案一定不会大于50000 * (10^7 - 0)^2 = 5 * 10^18(就是每个玩具一个容器),比2^63-1稍微小那么一点。
代码(288MS):
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long LL; const int MAXN = ; LL sum[MAXN], dp[MAXN];
int c[MAXN], n, L; LL sqrt_cost(int i, int j) {
return j - i + sum[j] - sum[i - ] - L;
} LL cost(int i, int j) {
LL res = sqrt_cost(i, j);
return res * res;
}
/*
bool check(int pos, int a, int b) {
return dp[a] + cost(a + 1, pos) >= dp[b] + cost(b + 1, pos);
}
*/
bool check(int pos, int a, int b) {
LL aa = dp[a], bb = sqrt_cost(a + , pos), cc = dp[b], dd = sqrt_cost(b + , pos);
return (cc - aa - ) / (bb - dd) + <= bb + dd;
} int binary_search(int st, int ed, int a, int b) {
int l = st, r = ed;
while(l < r) {
int mid = (l + r) >> ;
if(!check(mid, a, b)) l = mid + ;
else r = mid;
}
return l;
} struct Node {
int pos, best;
Node() {}
Node(int pos, int best): pos(pos), best(best) {}
} stk[MAXN];
int top; LL solve() {
int v = ;
stk[++top] = Node(, );
for(int i = ; i <= n; ++i) {
if(v < top && stk[v + ].pos <= i) ++v;
int p = stk[v].best;
dp[i] = dp[p] + cost(p + , i); while(v < top && check(stk[top].pos, stk[top].best, i))
--top;
int r = stk[top + ].pos ? stk[top + ].pos + : n + ;
int t = binary_search(max(stk[top].pos, i) + , r, stk[top].best, i);
if(t <= n) stk[++top] = Node(t, i);
}
return dp[n];
} int main() {
scanf("%d%d", &n, &L);
for(int i = ; i <= n; ++i) scanf("%d", &c[i]);
for(int i = ; i <= n; ++i) sum[i] = sum[i - ] + c[i];
cout<<solve()<<endl;
}
BZOJ 1010 玩具装箱toy(四边形不等式优化DP)(HNOI 2008)的更多相关文章
- BZOJ 1010 玩具装箱toy(斜率优化DP)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1010 题目大意:P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他 ...
- P3195 [HNOI2008]玩具装箱TOY(斜率优化dp)
P3195 [HNOI2008]玩具装箱TOY 设前缀和为$s[i]$ 那么显然可以得出方程 $f[i]=f[j]+(s[i]-s[j]+i-j-L-1)^{2}$ 换下顺序 $f[i]=f[j]+( ...
- BZOJ 1010: [HNOI2008]玩具装箱toy(斜率优化dp)
http://www.lydsy.com/JudgeOnline/problem.php?id=1010 题意: 思路: 容易得到朴素的递归方程:$dp(i)=min(dp(i),dp(k)+(i-k ...
- BZOJ 1010: 玩具装箱toy (斜率优化dp)
Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1... ...
- 2018.09.05 bzoj1010: [HNOI2008]玩具装箱toy(斜率优化dp)
传送门 一道经典的斜率优化dp. 推式子ing... 令f[i]表示装前i个玩具的最优代价. 然后用老套路. 我们只考虑把第j+1" role="presentation" ...
- _bzoj1010 [HNOI2008]玩具装箱toy【斜率优化dp】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1010 裸的斜率优化,第一次写队首维护的时候犯了个智障错误,队首维护就是维护队首,我怎么会那队 ...
- bzoj 1010 玩具装箱toy -斜率优化
P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具,第i件玩具 ...
- BZOJ 1010 [HNOI2008]玩具装箱toy:斜率优化dp
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1010 题意: 有n条线段,长度分别为C[i]. 你需要将所有的线段分成若干组,每组中线段的 ...
- BZOJ 1010: [HNOI2008]玩具装箱toy | 单调队列优化DP
原题: http://www.lydsy.com/JudgeOnline/problem.php?id=1010 题解: #include<cstdio> #include<algo ...
随机推荐
- Bluetooth GAP介绍
目录 1 GAP协议栈 2 Profile Role 3 用户接口 4 模式 5 安全 5.1 认证(Authentication) 5.2 安全模式 6 Idle Mode Procedures 7 ...
- Bluetooth RFCOMM介绍
目录 1. 介绍 2. 服务概述 2.1 RS-232控制信号 2.2 Null Modem Emulation 2.3 多串口仿真 3. 服务接口描述 4. RFCOMM帧类型 5. RFCOMM帧 ...
- Http响应code
Http响应报文 HTTP响应也由三个部分组成,分别是:状态行.消息报头.响应正文. 其中,HTTP-Version表示服务器HTTP协议的版本:Status-Code表示服务器发回的响应状态代码:R ...
- C++ 线程类的一个实现
.h #ifndef CTHREAD_H_ #define CTHREAD_H_ #include "plat.h" class CThread { public: enum { ...
- 让Eclipse不格式化数组或某段代码
用过eclipse ctrl+shit+f的人肯定都感觉eclipse这个功能很爽. 但对于数组,有时候就不是这样了. 比如在opengl中定义一些顶点信息: int one = 0x010000; ...
- 学习一下Fiddler的强大
①引言:Fiddler (中文名称:小提琴)是一个 HTTP 的调试代理,以代理服务器的方式,监听系统的Http网络数据流动, Fiddler 可以也可以让你检查所有的 HTTP 通讯,设置断点,以及 ...
- JQuery事件的链式写法
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- Java学习-032-JavaWeb_001 -- Tomcat环境部署及基本配置
首先到 Tomcat 官网,下载对应的版本,我本机的系统是 WIN7 64BIT 的,因而我选择的是64bit 的zip包,如下图所示:
- LeetCode Find Minimum in Rotated Sorted Array II
原题链接在这里:https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/ 题目: Follow up for &qu ...
- C语言:其他进制数转换为十进制(方法一)
#include<stdio.h> #include<math.h> #include<string.h> //其他任意进制转换为十进制 int main() { ...