• [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++!)

  • 相关阅读:
    Get distinct count of rows in the DataSet
    单引号双引号的html转义符
    PETS Public English Test System
    Code 39 basics (39条形码原理)
    Index was outside the bounds of the array ,LocalReport.Render
    Thread was being aborted Errors
    Reportviewer Error: ASP.NET session has expired
    ReportDataSource 值不在预期的范围内
    .NET/FCL 2.0在Serialization方面的增强
    Perl像C一样强大,像awk、sed等脚本描述语言一样方便。
  • 原文地址:https://www.cnblogs.com/Daz-Os0619/p/11699562.html
Copyright © 2020-2023  润新知