ZOJ3872 Beauty Of Array

题目链接:http://acm.zju.edu.cn/onlinejudge/showContestProblem.do?problemId=5496

题意:给定一些数字,要求取连续的一段数,和为其中所有元素和(出现多次只算一次)。问所有取法的和的和。

思路:按照一个一个往里添加元素的思想,dp即可。具体的话设前i-1个元素(inclusive)不重复,i与第j个元素重复,则dp[i] = (i-j)*s[i] + dp[i-1]。简单题。

源码:

#include <cstdio>

#include <cmath>

#include <cstring>

#include <algorithm>

#include <iostream>

#include <queue>

#include <map>

#define gmax(a,b) a>b?a:b

#define gmin(a,b) a<b?a:b

using namespace std;

typedef long long ll;

int const MAXN = 100000+5;

int s[MAXN],use[MAXN*10];

ll dp[MAXN];

void check(int n)

{

    printf("dp = \n");

    for(int i=1; i<=n; i++)

        printf("%d ",dp[i]);

    printf("\n");

}

int main()

{

    int t;scanf("%d",&t);

    while(t--){

        memset(use,0,sizeof(use));

        int n;

        ll ans = 0;

        scanf("%d",&n);

        for(int i=1; i<=n; i++){

            scanf("%d",&s[i]);

            if(i==1)    {dp[i] = s[i];

                    use[s[i]] = i;

            }

            else{

//                if(i==4)

//                    printf("use 4 = %d\n",use[s[i]]);

                if(use[s[i]]!=0){

//                    printf("use = %d\n",use[s[i]]);

                    dp[i] = dp[i-1] + (i-use[s[i]])*s[i];

                    use[s[i]] = i;

                }

                else{

                    use[s[i]] = i;

                    dp[i] = i*s[i] + dp[i-1];

                }

            }

            ans += dp[i];

//            printf("%I64d\n",ans);

        }

//        check(n);

        printf("%lld\n",ans);

    }

    return 0;

}

 

你可能感兴趣的:(校赛)