HDU 5586 Sum(最大连续子序列和)——BestCoder Round #64(div.1 div.2)

Sum

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 0    Accepted Submission(s): 0


Problem Description
There is a number sequence  A1,A2....An ,   you can select a interval [l,r] or not,all the numbers  Ai(lir)      will become  f(Ai) . f(x)=(1890x+143)mod10007 .After that,the sum of n numbers should be as much as possible.What is the maximum sum?
 

Input
There are multiple test cases.
First line of each case contains a single integer n. (1n105)
Next line contains n integers  A1,A2....An . (0Ai104)
It's guaranteed that  n106 .
 

Output
For each test case,output the answer in a line.
 

Sample Input
   
   
   
   
2 10000 9999 5 1 9999 1 9999 1
 

Sample Output
   
   
   
   
19999 22033
 

Source
BestCoder Round #64 (div.2)
 

/************************************************************************/

附上该题对应的中文题

Sum

 
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
给n个数{A}_{1},{A}_{2}....{A}_{n}A1,A2....An,你可以选择一个区间(也可以不选),区间里每个数x变成f(x),其中f(x)=(1890x+143) mod 10007f(x)=(1890x+143)mod10007。问最后n个数之和最大可能为多少。
输入描述
输入有多组数据。
每组数据第一行包含一个整数n.(1\leq n\leq {10}^{5})(1n105)
第二行n个整数{A}_{1},{A}_{2}....{A}_{n}A1,A2....An.(0\leq {A}_{i}\leq {10}^{4})(0Ai104)
数据保证 \sum n\leq {10}^{6}n106.
输出描述
对于每组数据输出一行答案.
输入样例
2
10000 9999
5
1 9999 1 9999 1
输出样例
19999
22033
/****************************************************/

出题人的解题思路:

Sum

{A}_{i}=f({A}_{i})-{A}_{i}Ai=f(Ai)Ai,然后求一遍最大连续子序列和就能知道最多能增加的值。

首先,先离线求出f(x)的值,对于f(x)-x可以知道数x改变之后是变大了还是变小了,然后套一下最大连续子序列和的模板,就可以求出结果了

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 100005;
const int M = 10005;
const int inf = 1000000000;
const int mod = 10007;
int s[N],a[N],b[N];
__int64 f_max(__int64 a,__int64 b)
{
    return a>b?a:b;
}
int main()
{
    int n,i,j;
    __int64 ans,sum,last;
    for(i=0;i<10000;i++)
        s[i]=(i*1890+143)%mod-i;
    while(~scanf("%d",&n))
    {
        for(sum=0,i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            sum+=a[i];
            b[i]=s[a[i]];
        }//printf("%I64d\n",ans);
        last=ans=0;
        for(i=1;i <= n;i++)
        {
            last=f_max(0,last)+b[i];
            ans=f_max(ans,last);
        }
        printf("%I64d\n",sum+ans);
    }
    return 0;
}
菜鸟成长记

你可能感兴趣的:(dp,ACM)