zoukankan      html  css  js  c++  java
  • 题解 lg2034 选择数字

    题意

    给定一行n个非负整数a[1]..a[n]。现在你可以选择其中若干个数,但不能有超过k个连续的数字被选择。你的任务是使得选出的数字的和最大。

    思路

    (f(i,0))表示考虑到数字(i)并选择(i)的最大和,(f(i,1))表示考虑到数字(i)并选择(i)的最大和

    那么

    [f(i,0)=min(f(i-1,0),f(i-1,1)) ]

    [f(i,1)=min(f(j,0)+sum_i-sum_j),i-kleq j leq i-1 ]

    然后就可以单调队列优化了

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    int const MAXN=1e5+10;
    int n,k;
    int f[MAXN][2],e[MAXN],q[MAXN],d[MAXN];
    
    signed main(){
    	scanf("%lld%lld",&n,&k);
    	for(int i=1;i<=n;i++){
    		scanf("%lld",&e[i]);
    		e[i]+=e[i-1];
    	}
    	int h=0,t=1;
    	for(int i=1;i<=n;i++){
    		f[i][0]=max(f[i-1][0],f[i-1][1]);
    		while(h<=t && q[h]<i-k)h++;
    		f[i][1]=e[i]+d[q[h]];
    		d[i]=f[i][0]-e[i];
    		while(h<=t && d[q[t]]<=d[i])t--;
    		q[++t]=i;
    	}
    	printf("%lld
    ",max(f[n][0],f[n][1]));
    	return 0;
    }
    
  • 相关阅读:
    2015第14周四
    2015第14周三
    2015第14周二
    2015第14周一
    2015第13周日
    2015第13周六
    2015第13周五
    2015第13周四
    2015第13周三
    2015第13周二
  • 原文地址:https://www.cnblogs.com/fpjo/p/13961250.html
Copyright © 2011-2022 走看看