zoukankan      html  css  js  c++  java
  • bzoj 3156: 防御准备【斜率优化dp】

    就是套路咯,设s[i]为1+2+...i
    首先列出dp方程( f[i]=min(f[j]+a[i]+(i-j)*i-(s[i]-s[j])) )
    然后推一推

    [f[i]=f[j]+a[i]+(i-j)*i-(s[i]-s[j]) ]

    [f[i]=f[j]+a[i]+i*i-i*j-s[i]+s[j] ]

    [i*j+f[i]=f[j]+s[j]+i*i+a[i]-s[i] ]

    [k=i,b=f[i],y=f[j]+s[j]+i*i+a[i]-s[i] ]

    就没啦

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int N=1000005,inf=1e9;
    int n,q[N],l,r;
    long long a[N],f[N],s[N];
    int read()
    {
    	int r=0,f=1;
    	char p=getchar();
    	while(p>'9'||p<'0')
    	{
    		if(p=='-')
    			f=-1;
    		p=getchar();
    	}
    	while(p>='0'&&p<='9')
    	{
    		r=r*10+p-48;
    		p=getchar();
    	}
    	return r*f;
    }
    double wk(int j,int k)
    {
    	return (double)(f[j]+s[j]-f[k]-s[k])/(double)(j-k);
    }
    int main()
    {
    	n=read();
    	for(int i=1;i<=n;i++)
    		a[i]=read(),s[i]=s[i-1]+i;
    	// for(int i=1;i<=n;i++)
    	// {
    		// f[i]=inf;
    		// for(int j=0;j<i;j++)
    			// f[i]=min(f[i],f[j]+a[i]+(i-j)*i-(s[i]-s[j]));
    	// }
    	for(int i=1;i<=n;i++)
    	{
    		while(l<r&&wk(q[l+1],q[l])<i)
    			l++;
    		f[i]=f[q[l]]+a[i]+1ll*(i-q[l])*i-(s[i]-s[q[l]]);
    		while(l<r&&wk(q[r-1],q[r])>wk(q[r],i))
    			r--;
    		q[++r]=i;
    	}
    	printf("%lld
    ",f[n]);
    	return 0;
    }
    
  • 相关阅读:
    区间树
    最大流
    单源最短路径
    散列表
    最小生成树
    软件体系结构2
    软件体系结构
    Leetcode 687.最长同值路径
    Leetcode 686.重复叠加字符串匹配
    Python测试框架
  • 原文地址:https://www.cnblogs.com/lokiii/p/9115760.html
Copyright © 2011-2022 走看看