hdu3507Print Article (斜率dp水题)

来源:互联网 发布:科比知乎 编辑:程序博客网 时间:2024/05/17 03:38

论文:NOI2004年周源的论文《浅谈数形结合思想在信息学竞赛中的应用》,

JSOI2009集训队论文 《

参考:http://www.cnblogs.com/kuangbin/archive/2012/08/26/2657650.html

//#pragma warning (disable: 4786)//#pragma comment (linker, "/STACK:16777216")//HEAD#include <cstdio>#include <ctime>#include <cstdlib>#include <cstring>#include <queue>#include <string>#include <set>#include <stack>#include <map>#include <cmath>#include <vector>#include <iostream>#include <algorithm>using namespace std;//LOOP#define FE(i, a, b) for(int i = (a); i <= (b); ++i)#define FED(i, b, a) for(int i = (b); i>= (a); --i)#define REP(i, N) for(int i = 0; i < (N); ++i)#define CLR(A,value) memset(A,value,sizeof(A))//INPUT#define RI(n) scanf("%d", &n)#define RII(n, m) scanf("%d%d", &n, &m)#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)#define RS(s) scanf("%s", s)typedef long long LL;const int INF = 1000000007;const double eps = 1e-10;const int MAXN = 500010;int n, M;int dp[MAXN];int sum[MAXN];int q[MAXN];int be, ed;int Up(int k, int j){    return dp[j] + sum[j] * sum[j] - (dp[k] + sum[k] * sum[k]);}int Down(int k, int j){    return (sum[j] - sum[k]) * 2;}int getDp(int i, int j){    return dp[j] + (sum[i] - sum[j]) * (sum[i] - sum[j]) + M;}int solve(){    dp[0] = 0;    be = 1;    ed = 0;    q[++ed] = 0;///    for (int i = 1; i <= n; i++)    {        while (be < ed && Up(q[be], q[be + 1]) <= sum[i] * Down(q[be], q[be + 1]))            be++;        int j = q[be];        dp[i] = getDp(i, j);        while (be < ed && Up(q[ed - 1], q[ed]) * Down(q[ed], i) >= Up(q[ed], i) * Down(q[ed - 1], q[ed]))            ed--;        q[++ed] = i;    }    return dp[n];}int main (){    int x;    while (~RII(n, M))    {        sum[0] = 0;        FE(i, 1, n)        {            RI(x);            sum[i] = sum[i - 1] + x;        }        printf("%d\n", solve());    }    return 0;}


原创粉丝点击