SCU2016-01 I题 二分 + 斜率优化dp
2016-09-04 16:07
393 查看
分析:
套路题。
套路题。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define pr(x) cout << #x << ": " << x << " " #define pl(x) cout << #x << ": " << x << endl; typedef long long ll; const int N = 2e5+5; ll val , sum = {0}, p = {0}; int q , top, tail; inline ll y(int x){ return p[x] - x*sum[x]; } double g(int j, int k){ double dy = y(j) - y(k); double dx = j - k; return dy/dx; } inline ll getans(int i, int j){ return p[i] - p[j] - j*(sum[i] - sum[j]); } int solve(ll x){ int l = top, r = tail-1, mid, res = l; while(l <= r){ //根据斜率二分求最优点 mid = (l+r) >> 1; if(g(q[mid], q[mid-1]) < -x) l = mid+1, res = mid; else r = mid-1; } return q[res]; } int main(){ #ifdef LOCAL freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); #endif int T =1 ; // scanf("%d", &T); while (T--) { int n; scanf("%d", &n); for(int i = 1; i <= n; ++i){ scanf("%lld", val+i); sum[i] = sum[i-1] + val[i]; p[i] = p[i-1] + i*val[i]; } top = tail = 0; q[tail++] = 0; ll ans = 0; for(int i = 1; i <= n; ++i){ int j = solve(sum[i]); //对于固定的i,二分求最优点 ans = max(ans, getans(i,j)); //更新答案 while(top < tail-1 && g(i, q[tail-1]) < g(q[tail-1], q[tail-2])) tail--;//满足了g(i,j)<g(j,k) q[tail++] = i; } printf("%lld\n", ans); } }
相关文章推荐
- Zsh简介与使用
- app接入支付宝后,支付成功后,回调不响应
- [ASP.NET MVC 小牛之路]14 - Unobtrusive Ajax
- 2016.9.4 の 測試
- csu1023
- 常见设备查询方式
- Javascript中关于跨域访问的学习笔记
- [ASP.NET MVC 小牛之路]13 - Helper Method
- 数组模拟实现邻接表
- 网站前端_JavaScript-基础入门.0004.JavaScript数据类型
- [ASP.NET MVC 小牛之路]12 - Section、Partial View 和 Child Action
- 第5题 查找字符串中的最长回文字符串---Manacher算法
- 写了2个小游戏项目斗地主,麻将
- MyBatis mapper文件中的变量引用方式#{}与${}的差别
- 阿狸面经(牛客网)
- 常见错误
- interface f0/0与interface serial0/0的区别
- 258. Add Digits
- Java中删除文件、删除目录及目录下所有文件
- ajax