zoukankan      html  css  js  c++  java
  • Cut the Sequence

    POJ

    题意:给定一个长度为N((N<=10^5))的序列A,要求把该序列分成若干段,在满足"每段中所有数的和"不超过M((M<=10^{11}))的前提下,让"每段中所有数的最大值"之和最小.求出最小值.

    分析:设(f[i])表示把前i个数分成若干段且满足条件的最小值.

    (f[i]=min_{0<=j<i,sum_{k=j+1}^iA_k<=m}f[j]+max_{j+1<=k<=i}A_k)

    二分(nlogn)预处理出对于每个i,满足(sum_{k=j+1}^iA_k<=m)的最小的j值,记为(c[i]).

    对于(max_{j+1<=k<=i}A_k)采用单调队列优化.

    处理好了以上两个就可以直接转移了(f[i]=f[c[i]]+a[q[l]])

    如何计算(max_{j+1<=k<=i}A_k)?有两种方法,一是ST,二是利用本题单调队列性质,队列中某一项的(max_{j+1<=k<=i}A_k)就是队列下一个元素的A值.(方法一易证难写,本人搞了半个多小时还是WA;方法二不知道证但容易写,一行代码.)

    记得开long long...

    //#include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #define LL long long
    using namespace std;
    inline LL read(){
        LL s=0,w=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
        return s*w;
    }
    const int N=100005;
    LL a[N],c[N],q[N],f[N],sum[N];
    int main(){
        LL n=read(),m=read();int bj=1;
        for(int i=1;i<=n;i++){
    		a[i]=read();
    		if(a[i]>m)bj=0;
    		sum[i]=sum[i-1]+a[i];
        }
        if(!bj){puts("-1");return 0;}
        for(int i=1;i<=n;i++){
    		int l=1,r=i,mid,cnt;
    		while(l<=r){
    	    	mid=(l+r)>>1;
    	    	if(sum[i]-sum[mid-1]<=m)cnt=mid,r=mid-1;
    	    	else l=mid+1;
    		}
    		c[i]=cnt-1;
        }
        int l=1,r=0;
        for(int i=1;i<=n;i++){
    		while(l<=r&&a[q[r]]<=a[i])r--;
    		q[++r]=i;
    		while(l<=r&&q[l]<=c[i])l++;
    		f[i]=f[c[i]]+a[q[l]];
    		for(int j=l;j<=r;j++){
    	    	f[i]=min(f[i],f[q[j]]+a[q[j+1]]);
    		}
        }
        printf("%lld
    ",f[n]);
        return 0;
    }
    
    
  • 相关阅读:
    python基本数据类型之字符串(二)
    python基本数据类型之字符串(一)
    Java基础之Java简介
    1024lab-How to run project using .ipynb
    pytorch调试工具
    关于深度学习选择和使用GPU
    中文文本预处理
    GCN相关
    Bert project Debug记录
    图卷积相关的参考
  • 原文地址:https://www.cnblogs.com/PPXppx/p/10958822.html
Copyright © 2011-2022 走看看