[NOIP普及2013] 小朋友的数字

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[NOIP普及2013] 小朋友的数字相关的知识,希望对你有一定的参考价值。

我可能今天智商不在线?

读题读不懂?

让我们来看两段的描述:

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

如果你开开心心去写连续子段和,恭喜你~WA了。因为题目的意思是前面任意一个小朋友的数字的最大值(但要要保证连续)

  • 第一个小朋友的分数是他的特征值,其它小朋友的分数为排在他前面的所有小朋友中(不包括他本人),小朋友分数加上其特征值的最大值。

如果你看到其特征值产生了疑惑,其到底是当前的小朋友本人,还是选择加的那个小朋友。不要着急请看样例。

#include <cstdio>
#include <algorithm>
#include <cstring>
typedef long long ll;
int n;
ll a[1000005];
ll mod,dp[1000005],Max;
ll Sum[1000005];

const int INF = 0x3f3f3f3f;

int main(){
    scanf("%d%lld",&n,&mod);
    for(int i=1;i<=n;++i){
        scanf("%lld",&a[i]);
        dp[i] = std::max(dp[i-1]+a[i],a[i]);
    } 
    for(int i=2;i<=n;++i){
        dp[i] = std::max(dp[i-1],dp[i]);
        //printf("dp[%d]:%lld\n",i,dp[i]);
        //printf("i:%d - %lld\n",i,Max);
    }
    Sum[1] = dp[1];
    Sum[2] = dp[1] + dp[1];
    bool flag=0;
    //for(int i=1;i<=n;++i) printf("dp[%d]:%lld\n",i,dp[i]);
    for(int i=3;i<=n;i++){
        Sum[i]+=Sum[i-1];
        if(dp[i-1] > 0) Sum[i]+=dp[i-1];
        if(Sum[i] > Sum[1]) flag=1;
        if(flag==1) Sum[i]%=mod;
    }
    //for(int i=1;i<=n;i++) printf("dp[%d]:%lld\n",i,Sum[i]);
    if(flag) printf("%lld\n",Sum[n]);
    else printf("%lld\n",Sum[1]);
    return 0;
}

 

以上是关于[NOIP普及2013] 小朋友的数字的主要内容,如果未能解决你的问题,请参考以下文章

小朋友的数字(NOIP2013 普及组第三题)

洛谷 P1982 小朋友的数字(NOIp2013普及组T3)

洛谷 P1980 记数问题 2013年NOIP全国联赛普及组

记数问题(NOIP2013 普及组第一题)

表达式求值(NOIP2013 普及组第二题)

NOIP2013pj小朋友的数字[DP 最大子段和]