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)的更多相关文章

  1. BZOJ 1010 玩具装箱toy(斜率优化DP)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1010 题目大意:P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他 ...

  2. 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]+( ...

  3. BZOJ 1010: [HNOI2008]玩具装箱toy(斜率优化dp)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1010 题意: 思路: 容易得到朴素的递归方程:$dp(i)=min(dp(i),dp(k)+(i-k ...

  4. BZOJ 1010: 玩具装箱toy (斜率优化dp)

    Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1... ...

  5. 2018.09.05 bzoj1010: [HNOI2008]玩具装箱toy(斜率优化dp)

    传送门 一道经典的斜率优化dp. 推式子ing... 令f[i]表示装前i个玩具的最优代价. 然后用老套路. 我们只考虑把第j+1" role="presentation" ...

  6. _bzoj1010 [HNOI2008]玩具装箱toy【斜率优化dp】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1010 裸的斜率优化,第一次写队首维护的时候犯了个智障错误,队首维护就是维护队首,我怎么会那队 ...

  7. bzoj 1010 玩具装箱toy -斜率优化

    P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具,第i件玩具 ...

  8. BZOJ 1010 [HNOI2008]玩具装箱toy:斜率优化dp

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1010 题意: 有n条线段,长度分别为C[i]. 你需要将所有的线段分成若干组,每组中线段的 ...

  9. BZOJ 1010: [HNOI2008]玩具装箱toy | 单调队列优化DP

    原题: http://www.lydsy.com/JudgeOnline/problem.php?id=1010 题解: #include<cstdio> #include<algo ...

随机推荐

  1. 第四章 跨平台图像显示库——SDL 第一节 与SDL第一次亲密接触

    http://blog.csdn.net/visioncat/article/details/1596576 GCC for Win32 开发环境介绍(5) 第四章 跨平台图像显示库——SDL 第一节 ...

  2. OC文件大小的计算方法,多用于清理缓存

    OC文件大小的计算方法,一般多用于清理缓存.下载.统计 可以使用以下方法: #pragma mark Bt转换 + (NSString *)axcFileSizeWithToString:(unsig ...

  3. Region的预分区

    1.预分区的方式 共有四种方式 2.帮助信息 help 'create' 3.第一种方式 4.在页面上查看效果(端口号:60010) 5.第二种方式 )创建文件,并在文件中书写分区的值 )创建表 6. ...

  4. [LeetCode] Edit Distance(很好的DP)

    Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2 ...

  5. leetcode:Factorial Trailing Zeroes

    Given an integer n, return the number of trailing zeroes in n!. 最初的代码 class Solution { public: int t ...

  6. leetcode:Valid Parentheses

    括号匹配 Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the ...

  7. 模糊搜索UISearchBar

    #import "Search_ViewController.h" @interface Search_ViewController ()<UITableViewDataSo ...

  8. ClassLoader

    1.双亲委派制 ClassLoadder是一个abstract类 static class sun.misc.Launcher$ExtClassLoader extends java.net.URLC ...

  9. webApi中参数传递

    webApi中参数传递 一:无参数的get方法: 前端:    function GetNoParam() { //为了统一:我们都采用$.ajax({}) 方法; $.ajax({ url: '/a ...

  10. 给ul中的li添加事件的多种方法

    给ul中的li添加事件的多种方法 这是一个常见,而且典型的前端面试题 <ul> <li>11111</li> <li>22222</li> ...