Sum
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1490 Accepted Submission(s): 758
Problem Description
There is a number sequence A1,A2....An ,you
can select a interval [l,r] or not,all the numbers Ai(l≤i≤r) 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.(1≤n≤105)
Next line contains n integersA1,A2....An .(0≤Ai≤104)
It's guaranteed that∑n≤106 .
First line of each case contains a single integer n.
Next line contains n integers
It's guaranteed that
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
思路:将每个数的f(x)-x存到新的数组中,求其中的最大连续字段和即可。
# include <bits/stdc++.h> # define f(x) (1890*x+143)%10007 using namespace std; int main() { int n, a, b, imin, imax, sum, sum2; while(~scanf("%d",&n)) { imin = sum = imax = sum2 = 0; while(n--) { scanf("%d",&a); b = f(a) - a; sum += a; sum2 += b; imax = max(imax, sum2-imin); imin = min(imin, sum2); } printf("%d\n",sum+imax); } return 0; }
下面是idealism_xxm的dp代码:
#include <cstdio> #include <algorithm> using namespace std; int n,num,i,dp[2][3];//dp[i&1][0]表示一直未进入置换区间,dp[i&1][1]表示当前处于置换区间,dp[i&1][2]表示当前已出置换区间(前面已经进入过了) inline int f() { return (1890*num+143)%10007; } int main() { while(1==scanf("%d",&n)) { dp[0][0]=dp[0][1]=dp[0][2]=0; for(i=1;i<=n;++i) { scanf("%d",&num); dp[i&1][0]=dp[(i-1)&1][0]+num; dp[i&1][1]=max(dp[(i-1)&1][0],dp[(i-1)&1][1])+f(); dp[i&1][2]=max(dp[(i-1)&1][1],dp[(i-1)&1][2])+num; } printf("%d\n",max(dp[n&1][0],max(dp[n&1][1],dp[n&1][2]))); } return 0; }