ACM学习历程—HDU5586 Sum(动态规划)(BestCoder Round #64 (div.2) 1002)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5586

题目大意就是把一段序列里面的数替换成f(x),然后让总和最大。

首先可以计算出初始的总和,以及每一个值换成f(x)的增益a[x]

那么就是求一段子序列a[x]的最值了,经典的DP

 

 

其实我一开始想到这个思路是因为列了一个式子:

 

S = sum(n)-sum(rt)+sum’(rt)-sum’(lt)+sum(lt)

 

=sum(n)+(sum’(rt)-sum’(lt))-(sum(rt)-sum(lt))

 

于是发现了就是求ltrt差值和的最值。

 

最后答案加上初始的总和输出。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <string>
#define LL long long

using namespace std;

const int maxN = 100004;
int n, a[maxN];
LL s;

void input()
{
    s = 0;
    int k;
    for (int i = 0; i < n; ++i)
    {
        scanf("%d", &k);
        s += k;
        a[i] = (1890*k+143)%10007-k;
    }
}

void work()
{
    LL ans = 0, now = 0;
    for (int i = 0; i < n; ++i)
    {
        if (now >= 0) now += a[i];
        else now = a[i];
        ans = max(ans, now);
    }
    cout << ans+s << endl;
}

int main()
{
    //freopen("test.in", "r", stdin);
    while (scanf("%d", &n) != EOF)
    {
        input();
        work();
    }
    return 0;
}
View Code

 

posted on 2015-11-28 21:52  AndyQsmart  阅读(193)  评论(0编辑  收藏  举报

导航