zoukankan      html  css  js  c++  java
  • 【题解】大朋友的数字

    题目链接:

    解:

    题意就是让我们求每次以a[i]结尾的最长不降子序列的和。

    那我们先预处理出来以每一个数结尾的最长不降子序列的长度,放在e[i]中,即以第i个数结尾。

    用基础dp求出即可。

    那么我们定义sum数组,表示以i结尾的最长不降子序列的和。

    那么枚举i之前的数,有:当e[i]==e[j]+1时,且a[i]>=a[j],即i可以是结尾时,sum[i]=sum[j]+a[i],直接跳出即可。

    最后输出就好了。

    代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #define inf 2147483647
    using namespace std;
    int len=1;
    int n,a[20001];
    int sum[20001];
    int pre[20001];
    int e[20001];
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)sum[i]=a[i],e[i]=1;
        /*for(int i=2;i<=n;i++){
            pre[1]=a[1];
            for(int j=2;j<=i;j++){
                if(a[j]>=pre[len])pre[++len]=a[j];
                else{
                    int p=upper_bound(pre+1,pre+len+1,a[j])-pre;
                    pre[p]=a[j];
                }
            }
            e[i]=len;
            len=1;
            memset(pre,0,sizeof(pre));
        }*/
        for(int i=2;i<=n;i++)
            for(int j=1;j<i;j++)
                if(a[i]>=a[j])e[i]=max(e[i],e[j]+1);
        for(int i=1;i<=n;i++)
            for(int j=1;j<i;j++)
                if(e[j]+1==e[i]&&a[i]>=a[j]){
                    sum[i]=sum[j]+a[i];
                    break;
                }
        //for(int i=1;i<n;i++)if(sum[i+1]<sum[i])sum[i+1]=sum[i];
        for(int i=1;i<=n;i++)printf("%d ",sum[i]);
        return 0;
    }

    注意,注释部分上面我用的(nlogn)算法求长度但是会超时,且注意倒数第二个循环中的判断。

  • 相关阅读:
    备忘录模式(java)
    06
    观察者模式(java)
    迭代器模式(c++)
    06
    07
    2021.11.21(迭代器模式c++)
    2021.11.24(状态模式java)
    2021.11.22(hive安装)
    2021.11.23(MYSQL安装)
  • 原文地址:https://www.cnblogs.com/h-lka/p/11140936.html
Copyright © 2011-2022 走看看