CSP-J 準決勝スプリントの必須回答質問 | P1982 子供の番号

幼い頃からC++を学びましょう!CSP-J 試験準備の学習プロセスにおける質問を記録し、あらゆる瞬間を記録します。

まとめ記事を添付します: CSP-J準決勝スプリント必須回答問題 | まとめ_プログラミング大好きコミュニケーターのブログ - CSDN Blog


[タイトル説明]

n 人の子供たちが一列に並んでいます 。すべての子供は手に数字を持っており、この数字は正または負の場合があります。各子供の特性値は、目の前の子供(自分を含む)のうち連続する数人(少なくとも一人)の子供の手の数字の合計の最大値に等しいと規定されています。

これらの子供たちの教師として、あなたは各子供に得点を与える必要があります。得点は次のように規定されています: 最初の子供の得点はその子供の特性値であり、他の子供の得点はその前の子供全員の得点です。彼 (彼を除く)、私)、子供のスコアにその固有値の最大値を加えたもの。

すべての子のスコアの最大値を計算し、出力時に最大値の符号を保持し、その絶対値を法 pで出力してください 。

【入力】

最初の行には、 スペースで区切られた2 つの正の整数npが含まれています。

2 行目には n 個の 数字が含まれており、各 2 つの整数はスペースで区切られており、各子供の手の番号を示しています。

【出力】

p を法とする最大スコアを表す整数 。

【入力サンプル】

5 997
1 2 3 4 5

【出力サンプル】

21

【詳しいコード説明】

#include <bits/stdc++.h>
using namespace std;
int n, p;
long long sum, maxv, ans;
long long a[1000005], b[1000005];  //a[]特征值,b[]分数
int main()
{
    cin >> n >> p;
    sum = 0;  //前面的数对后面值的贡献,小于0时赋值为0
    maxv = -1e9;
    for (int i=1; i<=n; i++) {
        int x;
        cin >> x;
        sum += x;
        maxv = max(maxv, sum);
        a[i] = maxv;  //非严格单调递增序列
        if (sum<0) sum=0;
    } 
    b[1]=a[1];
    b[2]=b[1]+a[1];
    int flag=0;
    for (int i=3; i<=n; i++) {
        //b[i-1]表示a[1]+b[1],a[2]+b[2],...,a[i-2]+b[i-2]的最大值
        b[i]=max(b[i-1]+a[i-1], b[i-1]);
        if (b[i]>b[1]) {
            flag=1;
            b[i]%=p;
        }
    }
    if (flag || n==2) ans = b[n];  //最后一个测试点数据是n==2时的特判
    else ans = b[1]%p;
    cout << ans;
    return 0;
}

【運用結果】

2 7
3 5
6

おすすめ

転載: blog.csdn.net/guolianggsta/article/details/133514234