• [P1982]小朋友的数字


    题目描述

    有 nn个小朋友排成一列。每个小朋友手上都有一个数字,这个数字可正可负。规定每个小朋友的特征值等于排在他前面(包括他本人)的小朋友中连续若干个(最少有一个)小朋友手上的数字之和的最大值。

    作为这些小朋友的老师,你需要给每个小朋友一个分数,分数是这样规定的:第一个小朋友的分数是他的特征值,其它小朋友的分数为排在他前面的所有小朋友中(不包括他本人),小朋友分数加上其特征值的最大值。

    请计算所有小朋友分数的最大值,输出时保持最大值的符号,将其绝对值对pp 取模后输出。

    输入格式

    第一行包含两个正整数 n,pn,p,之间用一个空格隔开。

    第二行包含 nn 个数,每两个整数之间用一个空格隔开,表示每个小朋友手上的数字。

    输出格式

    一个整数,表示最大分数对pp取模的结果。

    输入输出样例

    输入 #1
    5 997 
    1 2 3 4 5 
    
    输出 #1
    21
    
    输入 #2
    5 7 
    -1 -1 -1 -1 -1 
    
    输出 #2
    -1

    说明/提示

    Case 1:

    小朋友的特征值分别为 1,3,6,10,151,3,6,10,15,分数分别为1,2,5,11,211,2,5,11,21,最大值 2121对 997997 的模是 2121。

    Case 2:

    小朋友的特征值分别为-1,-1,-1,-1,-11,1,1,1,1,分数分别为-1,-2,-2,-2,-21,2,2,2,2,最大值-11对 77 的模为-11,输出-11。

    对于 50\%50%的数据,1 ≤ n ≤ 1,000,1 ≤ p ≤ 1,0001n1,000,1p1,000所有数字的绝对值不超过 10001000;

    对于 100\%100%的数据,1 ≤ n ≤ 1,000,000,1 ≤ p ≤ 10^91n1,000,000,1p10^9,其他数字的绝对值均不超过 10^9

    点这里收获更好的阅读体验

    大概思路:

    首先要把题面看懂。。。

    长得就很奇怪,其实仔细想想只要区分清楚特征值和分数就可以了。

    对于第i个人来说:

    特征值:求第i个人之前(包括第i个)的最大子段和即为特征值

    分数:第i个人之前(不包括第i个)的特征值加上初始数值的最大值

    (有点清楚了吗?)

    后面注意求最大子段和的小细节就可以了

    代码:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    long long int a[1000001],dp[1000001],sco[1000001],x;
    long long int n,p,ans;
    long long read()
    {
        long long x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
          {
            if(ch=='-')  f=-1;
            ch=getchar();
          }
        while(ch>='0'&&ch<='9')
          {
            x=x*10+ch-'0';
            ch=getchar();
          }
        return f*x;
    }
    int main()
    {
        n=read();
        p=read();
        long long int maxx=-0x7fffffff;
        for(int i=1;i<=n;i++)
        {
            x=read();
            if(a[i-1]>0)
            a[i]=a[i-1]+x;
            else
            a[i]=x;
            maxx=max(maxx,a[i]);
            dp[i]=maxx%p;
        } 
        ans=sco[1]=dp[1];
        maxx=-0x7ffffffff;
        for(int i=2;i<=n;i++)
        {
            maxx=max(maxx,sco[i-1]+dp[i-1]);
            sco[i]=maxx;
            if(ans<maxx)
            ans=maxx%p;
        }
        cout<<ans;
        return 0;
    }
    注意细节,先打再看

    再看一道名字有点像的题:

    题面点这里

    这题看起来很简单的亚子。。。

    其实就是解决两个问题:

    1.最长不下降子序列的长度

    2.1的和

    结合代码仔细想想就行:

    #include<iostream>
    using namespace std;
    int a[100001],v[1000001],f[1000001];
    int n;
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            v[i]=a[i];
            if(i>1)
            for(int j=1;j<i;j++)
            {
                if(a[j]<=a[i])
                {
                    if(f[i]<=f[j])
                    f[i]=f[j]+1,v[i]=v[j]+a[i];
                }
            }
            cout<<v[i]<<" ";
        }
        return 0;
    }
    先打再看

    (RP++!)

  • 相关阅读:
    VUE入门
    搭建内网穿透服务
    nacos集群配置安装
    jenkins入门
    Linux系统管理与自动化运维
    SVN
    JAR包启动
    服务器rm -rf 恢复案例 好文章
    docker入门到放弃
    CentOS7安装图形界面及报错处理
  • 原文地址:https://www.cnblogs.com/Daz-Os0619/p/11699562.html
Copyright © 2020-2023  润新知