zoukankan      html  css  js  c++  java
  • Codeforces 332B Maximum Absurdity(DP+前缀和处理)

    题目链接:http://codeforces.com/problemset/problem/332/B

    题目大意:
    给你n个数和一个整数k,要求找到不相交的两个长度为k的区间,使得区间和最大,输出这两个区间的起点。
    解题思路:
    先计算前缀和,然后预处理出maxsum[i],maxsum[i]记录i~n最大的长度为k子段的和。
    然后再去枚举即可。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<vector>
     5 #include<string>
     6 #include<string.h>
     7 #include<cctype>
     8 #include<math.h>
     9 #include<stdlib.h>
    10 #include<stack>
    11 #include<queue>
    12 #include<set>
    13 #include<map>
    14 #define lc(a) (a<<1)
    15 #define rc(a) (a<<1|1)
    16 #define MID(a,b) ((a+b)>>1)
    17 #define fin(name)  freopen(name,"r",stdin)
    18 #define fout(name) freopen(name,"w",stdout)
    19 #define clr(arr,val) memset(arr,val,sizeof(arr))
    20 #define _for(i,start,end) for(int i=start;i<=end;i++)  
    21 #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
    22 using namespace std;
    23 typedef long long LL;
    24 const int N=5e6+5;
    25 const LL INF64=1e18;
    26 const int INF=0x3f3f3f3f;
    27 const double eps=1e-10;
    28 
    29 LL sum[N];      //记录前缀和 
    30 LL maxsum[N]; //maxsum[i]记录i~n最大的长度为k子段的和 
    31 int idx[N];      //idx[i]记录相应的i~n最大子段的起点 
    32 
    33 int main(){
    34     FAST_IO;
    35     int n,k;
    36     cin>>n>>k;
    37     for(int i=1;i<=n;i++){
    38         cin>>sum[i];
    39         sum[i]+=sum[i-1];
    40     }
    41     int lim=n-k+1;
    42     for(int i=lim;i>=1;i--){
    43         LL now=sum[i+k-1]-sum[i-1]; //now为i~i+k-1之和  
    44         if(now>=maxsum[i+1]){        //因为要保证答案字典序最小,所以下标往小的取 
    45             maxsum[i]=now;
    46             idx[i]=i;
    47         }
    48         else{
    49             maxsum[i]=maxsum[i+1];
    50             idx[i]=idx[i+1];
    51         }
    52     }
    53 
    54     int st1=1,st2=k+1;
    55     LL mmax=sum[2*k];
    56     for(int i=1;i<=lim-k;i++){
    57         LL now=sum[i+k-1]-sum[i-1];
    58         if(now+maxsum[i+k]>mmax){ //maxsum[i+k]为i+k~n最大的长度为k的子段和
    59             mmax=now+maxsum[i+k];
    60             st1=i,st2=idx[i+k];
    61         }
    62     }
    63     cout<<st1<<" "<<st2<<endl;
    64     return 0;
    65 }
  • 相关阅读:
    bootstrap 网格系统学习
    在asp.net web api中利用过滤器设置输出缓存
    解决在开发环境中访问json配置文件时报HTTP 错误 404.3
    Newtonsoft.Json序列化和反序列
    装饰者模式学习
    SQL server跨库查询
    python-安装xlrd xlwt 插件
    vim 实际行跟屏幕行移动命令
    vim-缓存区中打开另外一个文件的方法
    vim 计算器寄存器使用
  • 原文地址:https://www.cnblogs.com/fu3638/p/9131472.html
Copyright © 2011-2022 走看看