CodeForces 631E Product Sum(斜率优化DP+二分|三分) ★
来源:互联网 发布:大数据就业方向 编辑:程序博客网 时间:2024/05/21 13:30
题意:给出n个数,现在可以移动一个数的位置,现在要使和sigma(ai*i)最大,询问这个最大和。
思路:将一个数向左移动和向右移动是一样的,现在考虑向左移动。
先预处理出前缀和,将一个数向左移动后,那么改变量为sum[r-1]-sum[l-1]+a[r]*(r-l),考虑枚举r,那么和r有关的数据就变成了常量。
现在问题转化成了求a[r]*l-sum[l-1],注意到这里l和sum[l-]都是递增的,所以可以考虑用斜率优化来加速dp,
维护一个下凸曲线,然后对于每一个a[r],二分斜率或者三分截距就可以解决当前位置左移的最大值。
直接三分:
#include <cstdio>#include <iostream>#include <cstring>#include <string>#include <cstdlib>#include <algorithm>#include <cmath>#include <vector>#include <set>#include <list>#include <queue>#include <map>#include <bitset>using namespace std;#define L(i) i<<1#define R(i) i<<1|1#define INF 0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-3#define maxn 200100#define MOD 1000000007int n;long long a[maxn],cur;long long total,sum[maxn];long long solve(int x,int y){ if(x <= y) return total - sum[y] + sum[x] + a[x] * (y - x); return total + sum[x-1] - sum[y-1] + a[x] * (y - x);}int main(){ int t; //scanf("%d",&t); while(scanf("%d",&n) != EOF) { sum[0] = 0; for(int i = 1; i <= n; i++) { scanf("%lld",&a[i]); sum[i] = sum[i-1] + a[i]; total += i * a[i]; } long long ans = -0x3f3f3f3f3f3f3f3f; for(int i = 1; i <= n; i++) { int l = 1,r = n; long long cur = -0x3f3f3f3f3f3f3f3f; while(l + 1 <= r) { int mid = l + (r - l) / 3; int mmid = r - (r - l) / 3; long long ans1 = solve(i,mid); long long ans2 = solve(i,mmid); if(ans1 > ans2) { r = mmid - 1; cur = max(cur,ans1); } else { l = mid + 1; cur = max(cur,ans2); } } cur = max(cur,solve(i,l)); ans = max(ans,cur); } printf("%lld\n",ans); } return 0;}
斜率优化:
#include<bits/stdc++.h>#define eps 1e-6#define LL long long#define pii pair<int, int>#define pb push_back#define mp make_pair//#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;const int MAXN = 200020;const LL INF = 1e17;int n;int a[MAXN];LL sumv[MAXN];int Q[MAXN], h, t;struct Point {LL x, y;Point(LL _x = 0, LL _y = 0) : x(_x), y(_y) {}} p[MAXN];LL getY(int k, int j) {return p[k].y-p[j].y;}LL getX(int k, int j) {return p[k].x-p[j].x;}bool check1(int k, int j) {return getY(Q[k+1], Q[k]) >= getX(Q[k+1], Q[k])*a[j]; }bool check2(int k, int j) {return getY(Q[k], Q[k+1]) <= getX(Q[k], Q[k+1])*a[j];}int main(){ //freopen("input.txt", "r", stdin);scanf("%d", &n);LL ans = 0;for (int i = 1; i <= n; i++) {scanf("%d", &a[i]);sumv[i] = sumv[i-1] + a[i];ans += (LL)i * a[i];}for (int i = 1; i <= n; i++) p[i] = Point(i, sumv[i-1]);LL tmp = ans;t = 0;for (int i = 2; i <= n; i++) {while (t > 1 && getY(i-1, Q[t])*getX(Q[t], Q[t-1]) <= getY(Q[t], Q[t-1])*getX(i-1, Q[t]))t--;Q[++t] = i-1;int l = 1, r = t;while (l < r) {int mid = (l+r) >> 1;if (check1(mid, i)) r = mid;else l = mid + 1;} ans = max(ans, tmp+(LL)a[i]*Q[r]-sumv[Q[r]-1]+sumv[i-1]-(LL)i*a[i]);}t = 0;for (int i = 1; i <= n; i++)p[i] = Point(i, sumv[i]);for (int i = n-1; i > 0; i--) {while (t > 1 && getY(Q[t], i+1)*getX(Q[t-1], Q[t]) >= getY(Q[t-1], Q[t])*getX(Q[t], i+1))t--;Q[++t] = i+1;int l = 1, r = t;while (l < r) {int mid = (l+r) >> 1;if (check2(mid, i)) r = mid;else l = mid + 1; } ans = max(ans, tmp+(LL)Q[r]*a[i]-(LL)i*a[i]-sumv[Q[r]]+sumv[i]);}printf("%I64d", ans); return 0;}
0 0
- CodeForces 631E Product Sum(斜率优化DP+二分|三分) ★
- CodeForces 631E Product Sum(斜率优化DP+二分|三分)
- Codeforces Round #344 (Div. 2) E - Product Sum (斜率dp)
- Codeforces Round #344 (Div. 2) E. Product Sum (三分)
- codeforces 631E Product Sum (dp凸单调性)
- Codeforces 631E:Product Sum
- Codeforces Round #344 (Div. 2) E - Product Sum(三分 (java))
- [斜率优化DP] codeforces 673E. Levels and Regions
- [Codeforces 673E] Levels and Regions (期望+斜率DP)
- DP训练 Codeforces 673E Levels and Regions [斜率优化dp][期望]
- Codeforces Round #351 (VK Cup 2016 Round 3, Div. 2 Edition) E. Levels and Regions(斜率优化dp) ★ ★ ★
- Codeforces 743E(二分+状压dp)
- DP(斜率优化)
- CF 189DIV2 E DP + 斜率优化
- Codeforces 643C Levels and Regions(斜率优化dp)
- bzoj1767 树上dp斜率优化+二分
- bzoj3156(斜率优化DP)
- poj1180(斜率优化dp)
- ios9 分享 打不开第三方应用
- Collections.synchronizedList
- php $_FILES 数组为 empty
- Android轮播图(ViewPage)
- 非递归遍历二叉树的方法
- CodeForces 631E Product Sum(斜率优化DP+二分|三分) ★
- Neptune分布式系统的流程、参数详解
- xxx cannot be resolved to a type 错误解决方法
- java生成json时产生栈溢出错误问题的解决
- Linux——自定义命令
- 代码命名规范
- Java 关键字synchronized解析
- php中计算一个字符在字符串中出现的次数
- CSS块元素和内联元素特征