zoukankan      html  css  js  c++  java
  • POJ 3709

    简单的单调队列优化,注意是哪些点加入队列即可。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #define N 500050
    #define LL __int64
    using namespace std;
    
    LL sum[N],dp[N]; int q[N];
    int a[N];
    int head,tail;
    
    LL getUp(int j,int k){
    	return dp[j]-sum[j]+a[j+1]*j-(dp[k]-sum[k]+a[k+1]*k);
    }
    
    LL getDown(int j,int k){
    	return a[j+1]-a[k+1];
    }
    
    int main(){
    	int n,T,tmp,k;
    	scanf("%d",&T);
    	while(T--){
    		scanf("%d%d",&n,&k);
    		sum[0]=0;
    		for(int i=1;i<=n;i++){
    			scanf("%d",&a[i]);
    			sum[i]=sum[i-1]+(LL)a[i];
    	//		cout<<sum[i]<<' ';
    			dp[i]=0;
    		}
    //		cout<<endl;
    		head=tail=0;
    		int i;
    		for(i=1;i<=2*k&&i<=n;i++){
    			dp[i]=sum[i]-sum[0]-((LL)a[1])*((LL)i);
    	//		cout<<dp[i]<<' ';
    		}
    	//	cout<<endl;
    		i--;
    		if(i==2*k){
    			dp[i]=min(dp[i],dp[k]+sum[i]-sum[k]-(LL)a[k+1]*(i-k));
    			q[tail++]=k;
    			q[tail++]=k+1;
    			for(++i;i<=n;i++){
    				dp[i]=sum[i]-sum[0]-((LL)a[1])*((LL)i);
    			//	cout<<dp[i]<<endl;
    				while(head<tail-1&&getUp(q[head+1],q[head])<=((LL)i)*getDown(q[head+1],q[head]))
    				head++;
    			//	cout<<q[head]<<endl;
    				dp[i]=min(dp[i],dp[q[head]]+sum[i]-sum[q[head]]-((LL)a[q[head]+1]*(LL)(i-q[head])));
    				while(head<tail-1&&getUp(i-k+1,q[tail-1])*getDown(q[tail-1],q[tail-2])<=getUp(q[tail-1],q[tail-2])*getDown(i-k+1,q[tail-1]))
    				tail--;
    				q[tail++]=i-k+1;
    			}
    		}
    		printf("%I64d
    ",dp[n]);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    聊聊Docker数据卷和数据卷容器
    Nginx虚拟主机
    Shell文本处理四剑客
    Docker镜像、容器剖析
    Tomcat性能优化及JVM内存工作原理
    Nginx动静分离架构&&HA-LB集群整合
    Mysql主从复制架构实战
    Mysql编译安装详解
    Apache虚拟主机实战
    Ansible性能调优
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4156475.html
Copyright © 2011-2022 走看看