[原题描述以及提交地址]: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:打斜率优化的时候一定要注意等号,而且最好从凸包的角度来理解,来实现,比较不容易出错。

  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <deque>
  4. const int N = 1000 + 9;
  5. typedef long long ll;
  6. int n,a[N],b[N],i,j,t;
  7. ll suma[N],sumb[N],f[N][N];
  8. std::deque<int> qi[N],qj[N];
  9. inline ll sqr(const ll x){return x*x;}
  10. inline ll calci(const int x)
  11. {return f[i - 1][x] - sqr(sumb[j - 1] - sumb[x]);}
  12. inline ll calcj(const int x)
  13. {return f[x][j - 1] - sqr(suma[i - 1] - suma[x]);}
  14. inline ll Xi(const int k,const int l)
  15. {return f[i - 1][k] - sqr(sumb[k]) - (f[i - 1][l] - sqr(sumb[l]));}
  16. inline ll Yi(const int k,const int l)
  17. {return sumb[l] - sumb[k];}
  18. inline ll Xj(const int k,const int l)
  19. {return f[k][j - 1] - sqr(suma[k]) - (f[l][j - 1] - sqr(suma[l]));}
  20. inline ll Yj(const int k,const int l)
  21. {return suma[l] - suma[k];}
  22. int main()
  23. {
  24. #ifndef ONLINE_JUDGE
  25. freopen("sxbk.in","r",stdin);
  26. freopen("sxbk.out","w",stdout);
  27. #endif
  28. scanf("%d",&n);
  29. for (i = 1; i <= n; ++i) {
  30. scanf("%d",a+i);
  31. suma[i] = suma[i - 1] + a[i];
  32. }
  33. for (i = 1; i <= n; ++i) {
  34. scanf("%d",b+i);
  35. sumb[i] = sumb[i - 1] + b[i];
  36. }
  37. for (i = 1; i <= n; ++i) {
  38. for (j = 1; j <= n; ++j) {
  39. while (qi[i - 1].size() > 1 && calci(qi[i - 1].front()) <= calci(qi[i - 1][1])) qi[i - 1].pop_front();
  40. while (qj[j - 1].size() > 1 && calcj(qj[j - 1].front()) <= calcj(qj[j - 1][1])) qj[j - 1].pop_front();
  41. f[i][j] = - sqr(suma[i - 1]) - sqr(sumb[j - 1]);
  42. if ((i - 1) && qi[i - 1].size()) f[i][j] = std::max(f[i][j],calci(qi[i - 1].front()));
  43. if ((j - 1) && qj[j - 1].size()) f[i][j] = std::max(f[i][j],calcj(qj[j - 1].front()));
  44. f[i][j] += a[i] * b[j];
  45. 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();
  46. 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();
  47. if (i - 1) qi[i - 1].push_back(j);
  48. if (j - 1) qj[j - 1].push_back(i);
  49. }
  50. }
  51. ll ans = -0x7fffffff;
  52. for (int i = 1; i <= n; ++i)
  53. ans = std::max(ans,std::max(f[i][n] - sqr(suma[n] - suma[i]),f[n][i] - sqr(sumb[n] - sumb[i])));
  54. printf("%I64d\n",ans);
  55. }

  

[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. git使用笔记(八)团队协作

    By francis_hao    Nov 24,2016       本文由 刘英皓 创作,采用 知识共享 署名-非商业性使用-相同方式共享 3.0 中国大陆 许可协议进行许可.欢迎转载,请注明出处 ...

  2. Java的外部类为什么不能使用private、protected进行修饰

    对于顶级类(外部类)来说,只有两种修饰符:public和默认(default).因为外部类的上一单元是包,所以外部类只有两个作用域:同包,任何位置.因此,只需要两种控制权限:包控制权限和公开访问权限, ...

  3. HDU 多校对抗赛 D Distinct Values

    Distinct Values Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  4. CSS3学习之radial-gradient(径向渐变)

    转自:http://www.cnblogs.com/rainman/p/5133685.html 1.语法 径向渐变不同于线性渐变,线性渐变是从“一个方向”向“另一个方向”的颜色渐变,而径向渐变是从“ ...

  5. CSS中z-index全解析

    一.z-index解释 z-index属性决定了一个HTML元素的层叠级别,元素层叠级别是相对于元素在Z轴上(与X轴Y轴相对照)的位置而言.一个更高的z-index值意味着这个元素在叠层顺序中会更靠近 ...

  6. demo 集合

    github: https://github.com/zhanghaifeng1234565/ProjectFunctionCollect        https://github.com/XY-W ...

  7. bzoj 1876 高精

    首先我们知道,对于两个数a,b,他们的gcd情况有如下形式的讨论 当a为奇数,b为偶数的时候gcd(a,b)=gcd(a div 2,b) 当b为奇数,a为偶数的时候gcd(a,b)=gcd(a,b ...

  8. sublime text 2学习(二):创建可复用的代码片段

    对于前端工程师来讲,写一个html页面的基本结构是体力活,每次去拷贝一个也麻烦,sublime text 2 提供了一个很好的复用代码片段.下面介绍一下创建一个html5的代码片段的过程. 在菜单上点 ...

  9. Linux 通过ssh传输文件

    一.scp是什么? scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的.可能会稍微影响 ...

  10. c 語言 控制碼

    source code #include <stdio.h> int main() { char *test = "ABC\x41\n"; printf("s ...