[原题描述以及提交地址]:http://acm.tongji.edu.cn/problem?pid=10011

[题目大意]

  给定两个长度为N的序列,要给这两个序列的数连线。连线只能在两个序列之间进行,且连线不能交叉,每个数最多只能选一次。连线从左到右进行,每次连线收益为这两个数的乘积。对于两个序列,都有:每段连续的没被选中的数的和的平方为损失。

防剧透

防剧透

防剧透

防剧透

防剧透

防剧透

防剧透

防剧透

防剧透

防剧透

防剧透

防剧透

防剧透

[解题思路]

  O(n^4):

  f[i][j]代表a序列前i个数,b序列前j个数中i,j必选所得到的最优收益。

  f[i][j] = a[i] * b[j] + max(f[k][l] - (suma[i - 1] - suma[k])^2 - (sumb[j - 1] - sumb[l])^2) {0 < k < i, 0 < l < j}

===================================================================================

  O(n^3):

  可以发现对于k + 1...i 以及 l + 1...j 这两段数之间可以再连线,而且答案不会更劣。

  于是有k == i - 1 or l == j - 1

  f[i][j] = a[i] * b[j] + max(f[k][j - 1] - (suma[i - 1] - suma[k])^2,f[i - 1][l] - (sumb[j - 1] - sumb[l])^2) {0 < k < i, 0 < l < j}

===================================================================================

  O(n^2):

  事实上以上的方程是可以用斜率优化的。只不过是同时依赖于两个斜率优化方程而已。于是,对于每个i,j开一个单调队列,维护即可。

===================================================================================

Postscript:打斜率优化的时候一定要注意等号,而且最好从凸包的角度来理解,来实现,比较不容易出错。

#include <cstdio>
#include <algorithm>
#include <deque>
const int N = 1000 + 9;
typedef long long ll;
int n,a[N],b[N],i,j,t;
ll suma[N],sumb[N],f[N][N];
std::deque<int> qi[N],qj[N];
inline ll sqr(const ll x){return x*x;}
inline ll calci(const int x)
{return f[i - 1][x] - sqr(sumb[j - 1] - sumb[x]);}
inline ll calcj(const int x)
{return f[x][j - 1] - sqr(suma[i - 1] - suma[x]);}
inline ll Xi(const int k,const int l)
{return f[i - 1][k] - sqr(sumb[k]) - (f[i - 1][l] - sqr(sumb[l]));}
inline ll Yi(const int k,const int l)
{return sumb[l] - sumb[k];}
inline ll Xj(const int k,const int l)
{return f[k][j - 1] - sqr(suma[k]) - (f[l][j - 1] - sqr(suma[l]));}
inline ll Yj(const int k,const int l)
{return suma[l] - suma[k];}
int main()
{
#ifndef ONLINE_JUDGE
freopen("sxbk.in","r",stdin);
freopen("sxbk.out","w",stdout);
#endif
scanf("%d",&n);
for (i = 1; i <= n; ++i) {
scanf("%d",a+i);
suma[i] = suma[i - 1] + a[i];
}
for (i = 1; i <= n; ++i) {
scanf("%d",b+i);
sumb[i] = sumb[i - 1] + b[i];
}
for (i = 1; i <= n; ++i) {
for (j = 1; j <= n; ++j) {
while (qi[i - 1].size() > 1 && calci(qi[i - 1].front()) <= calci(qi[i - 1][1])) qi[i - 1].pop_front();
while (qj[j - 1].size() > 1 && calcj(qj[j - 1].front()) <= calcj(qj[j - 1][1])) qj[j - 1].pop_front();
f[i][j] = - sqr(suma[i - 1]) - sqr(sumb[j - 1]);
if ((i - 1) && qi[i - 1].size()) f[i][j] = std::max(f[i][j],calci(qi[i - 1].front()));
if ((j - 1) && qj[j - 1].size()) f[i][j] = std::max(f[i][j],calcj(qj[j - 1].front()));
f[i][j] += a[i] * b[j];
while ((t = qi[i - 1].size()) > 1 && Xi(qi[i - 1][t - 2],qi[i - 1].back()) * Yi(qi[i - 1].back(),j) >= Xi(qi[i - 1].back(),j) * Yi(qi[i - 1][t - 2],qi[i - 1].back())) qi[i - 1].pop_back();
while ((t = qj[j - 1].size()) > 1 && Xj(qj[j - 1][t - 2],qj[j - 1].back()) * Yj(qj[j - 1].back(),i) >= Xj(qj[j - 1].back(),i) * Yj(qj[j - 1][t - 2],qj[j - 1].back())) qj[j - 1].pop_back();
if (i - 1) qi[i - 1].push_back(j);
if (j - 1) qj[j - 1].push_back(i);
}
}
ll ans = -0x7fffffff;
for (int i = 1; i <= n; ++i)
ans = std::max(ans,std::max(f[i][n] - sqr(suma[n] - suma[i]),f[n][i] - sqr(sumb[n] - sumb[i])));
printf("%I64d\n",ans);
}

  

[USACO Special 2007 Chinese Competition]The Bovine Accordion and Banjo Orchestra的更多相关文章

  1. 【BZOJ1713】[Usaco2007 China]The Bovine Accordion and Banjo Orchestra 音乐会 斜率优化

    [BZOJ1713][Usaco2007 China]The Bovine Accordion and Banjo Orchestra 音乐会 Description Input 第1行输入N,之后N ...

  2. BZOJ_1713_[Usaco2007 China]The Bovine Accordion and Banjo Orchestra 音乐会_斜率优化

    BZOJ_1713_[Usaco2007 China]The Bovine Accordion and Banjo Orchestra 音乐会_斜率优化 Description Input 第1行输入 ...

  3. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  4. [Elite 2008 Dec USACO]Jigsaw Puzzles

    #include <iostream> #include <cstdio> #include <cstring> using namespace std; #def ...

  5. Delphi QC 记录

    各网友提交的 QC: 官方网址 说明 备注 https://quality.embarcadero.com/browse/RSP-12985 iOS device cannot use indy id ...

  6. TOJ1693(Silver Cow Party)

    Silver Cow Party   Time Limit(Common/Java):2000MS/20000MS     Memory Limit:65536KByte Total Submit: ...

  7. 一些基于jQuery开发的控件

    基于jQuery开发,非常简单的水平方向折叠控件.主页:http://letmehaveblog.blogspot.com/2007/10/haccordion-simple-horizontal-a ...

  8. TOJ 1690 Cow Sorting (置换群)

    Description Farmer John's N (1 ≤ N ≤ 10,000) cows are lined up to be milked in the evening. Each cow ...

  9. TOJ1698: Balanced Lineup

    Description For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same ...

随机推荐

  1. cookie中的path与domain属性详解

    1.domain表示的是cookie所在的域,默认为请求的地址,如网址为www.jb51.net/test/test.aspx,那么domain默认为www.jb51.net.而跨域访问,如域A为t1 ...

  2. codeforces 719C. Efim and Strange Grade

    C. Efim and Strange Grade time limit per test 1 second memory limit per test 256 megabytes input sta ...

  3. bzoj 3771 Triple FFT 生成函数+容斥

    Triple Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 847  Solved: 482[Submit][Status][Discuss] Desc ...

  4. java获取mysql数据库表、字段、字段类型、字段注释

    最近想要写一个根据数据库表结构生成实体.mapper接口.mapping映射文件.service类的简单代码生成工具,所以查阅了一些资料,怎样获取数据库的表.表中字段.字段类型.字段注释等信息. 最后 ...

  5. SpringMVC学习 -- REST

    REST:表现层状态转化. REST 是目前最流行的一种互联网软件架构.他结构清晰.符合标准.易于理解.扩展方便 , 所以正得到越来越多网站的采用. 状态转化:浏览器 form 表单只支持 GET 和 ...

  6. 百度vue服务端渲染(ssr)有感

    前端各种框架工具层次不穷,日新月异,越学越混乱了快 知乎上看到了一段回复,豁然开朗的感觉. Web 2.0时代最大的思想革命本质不是前后端分离,而是把网页当作独立的应用程序(app).前后端分离只是实 ...

  7. 封装常用的Javascript跨浏览器方法

    var EventUntil={ // 跨浏览器的添加事件方法 addHandler:function(element,type,handler){ if(element.addEventListen ...

  8. Lucene4.6查询时完全跳过打分,提高查询效率的实现方式

    由于索引的文件量比较大,而且应用中不需要对文档进行打分,只需要查询出所有满足条件的文档.所以需要跳过打分来提高查询效率.一开始想用ConstantScoreQuery,但是测试发现这个类虽然让所有返回 ...

  9. struts2学习笔记(二)

    一. 国际化的目标 1). 如何配置国际化资源文件 I. Action 范围资源文件: 在Action类文件所在的路径建立名为 ActionName_language_country.properti ...

  10. 【Foreign】划分序列 [线段树][DP]

    划分序列 Time Limit: 20 Sec  Memory Limit: 256 MB Description Input Output 仅一行一个整数表示答案. Sample Input 9 4 ...