zoukankan      html  css  js  c++  java
  • 特别行动队「APIO 2010」

    题意

    有一个序列,要求将其分为任意部分。对于每一部分,其值为(at^2+bt+c),其中(t)为这一部分元素总和,(a,b,c)给定。


    思路

    容易推出状态转移方程为(f[i]=min(f[j]+a*(sum[i]-sum[j])^2+b*(sum[i]-sum[j])+c))

    朴素转移的时间复杂度为(n^2),考虑斜率优化。

    假设对于决策点(x,y),存在(f[x]+a*(sum[i]-sum[x])^2+b*(sum[i]-sum[x])+c>f[y]+a*(sum[i]-sum[y])^2+b*(sum[i]-sum[y])+c)

    可化简为(f[x]+a*sum[x]^2-b*sum[x]-2*sum[i]*sum[x]>f[y]+a*sum[y]^2-b*sum[y]-2*sum[i]*sum[y])

    (frac{f[x]+a*sum[x]^2-b*sum[x]-(f[y]+a*sum[y]^2-b*sum[y])}{sum[x]-sum[y]}>2*sum[i])

    (end)

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    namespace StandardIO {
    
    	template<typename T>inline void read (T &x) {
    		x=0;T f=1;char c=getchar();
    		for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1;
    		for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
    		x*=f;
    	}
    
    	template<typename T>inline void write (T x) {
    		if (x<0) putchar('-'),x*=-1;
    		if (x>=10) write(x/10);
    		putchar(x%10+'0');
    	}
    
    }
    
    using namespace StandardIO;
    
    namespace Project {
    	#define int long long
    	
    	const int N=1000010;
    	
    	int n;
    	int a,b,c,head,tail;
    	int sum[N],dp[N],queue[N];
    	
    	inline double slope (int x,int y) {
    		return (double)(dp[y]+a*sum[y]*sum[y]-b*sum[y]-dp[x]-a*sum[x]*sum[x]+b*sum[x])/(double)(sum[y]-sum[x]);
    	}
    	inline int f (int x) {
    		return a*x*x+b*x+c;
    	}
    
    	inline void MAIN () {
    		read(n);
    		read(a),read(b),read(c);
    		for (register int i=1; i<=n; ++i) {
    			read(sum[i]),sum[i]+=sum[i-1];
    		}
    		head=tail=1,queue[head]=0;
    		for (register int i=1; i<=n; ++i) {
    			while (head<tail&&slope(queue[head],queue[head+1])>=2*a*sum[i]) ++head;
    			dp[i]=dp[queue[head]]+f(sum[i]-sum[queue[head]]);
    			while (head<tail&&slope(queue[tail-1],queue[tail])<=slope(queue[tail],i)) --tail;
    			queue[++tail]=i;
    		}
    		write(dp[n]);
    	}
    	
    	#undef int
    }
    
    int main () {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	Project::MAIN();
    }
    
    
  • 相关阅读:
    .net core api服务端跨域配置
    在.net core web 项目中使用Nlog记录日志
    在windows7系统下如何查看及升级powershell到3.0版本
    Prism框架中的事件聚合器EventAggregator(上)
    前端生成 guid 的方法
    冒泡排序的过程以及讲解
    关于isNaN() 判断是否是非数字
    BFC问题
    标准盒模型和怪异盒模型宽高计算!
    Python网络编程篇
  • 原文地址:https://www.cnblogs.com/ilverene/p/11360926.html
Copyright © 2011-2022 走看看