• UVA 1619 Feel Good


    题意:

      给出n个正整数的序列,要求你找出符合sum(a1 + a2 + a3 + … + an) * min(a1,a2,…,an)的最大值,如果有多个符合条件的,输出最短序列.最短序列这点很重要。

    分析:  

      那就设两个数组,纪录已当前数位最小值所能覆盖的最大区间,然后枚举每个数,求出区间和再乘上当前数求得值再进行比较 .设置左右区间时,可以递归比较,假设l[i]纪录的时ai所能覆盖的最左端点,如果aj <= ai (j > i),那么l[j] = l[i]了,然后再不断的更新找寻即可.

      注意:sum数组,最大值要用long long。递归时l[i]从1-n,r[i]从n-1.不然会超时。

    代码:

      

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn=1000010;
    int n;
    int num[maxn];
    int l[maxn],r[maxn];
    long long sum[maxn];
    int main()
    {
    int cas=0;
    while(scanf("%d",&n)!=EOF)
    {
    if(cas)
    printf(" ");
    cas++;
    int i;
    sum[0]=0;
    memset(num,-1,sizeof(num));
    for(i=1;i<=n;i++)
    {
    scanf("%d",&num[i]);
    sum[i]=sum[i-1]+num[i];
    l[i]=i;
    r[i]=i;
    }
    for(i=1;i<=n;i++)
    {
    while(num[l[i]-1]>=num[i])
    l[i]=l[l[i]-1];
    }
    for(i=n;i>=1;i--)
    {
    while(num[r[i]+1]>=num[i])
    r[i]=r[r[i]+1];
    }
    long long MAX=0;
    int l1=1,r1=1;
    long long sum1;
    for(i=1;i<=n;i++)
    {
    sum1=(sum[r[i]]-sum[l[i]-1])*num[i];
    if(sum1>MAX||(sum1==MAX&&(r1-l1>r[i]-l[i])))
    {
    MAX=sum1;
    l1=l[i];
    r1=r[i];
    }
    }
    printf("%lld %d %d ",MAX,l1,r1);
    }
    }
  • 相关阅读:
    使用uibesizerpath + Cashaplayer画椭圆
    国庆节,回乡
    慎用单例
    终于碰到iOS对象集合深拷贝的坑
    Oracle 按表名导出数据
    代理模式(Proxy Pattern)
    享元模式(Flyweight Pattern)
    外观模式(Facade Pattern)
    组合模式
    装饰者模式
  • 原文地址:https://www.cnblogs.com/137033036-wjl/p/4934704.html
Copyright © 2020-2023  润新知