Given a set of n integers: A={a1, a2,..., an}, we define a function d(A) as below:
Your task is to calculate d(A).
Input
The input consists of T(<=30) test cases. The number of test cases (T) is given in the first line of the input.
Each test case contains two lines. The first line is an integer n(2<=n<=50000). The second line contains n integers: a1, a2, …, an. (|ai| <= 10000).There is an empty line after each case.
Output
Print exactly one line for each test case. The line should contain the integer d(A).
Sample Input
1
10
1 -1 2 2 3 -3 4 -4 5 -5
Sample Output
13
Hint
In the sample, we choose {2,2,3,-3,4} and {5}, then we can get the answer.
Huge input,scanf is recommended.
此题是最经典的最大两子段和,主要思路是从左右开工,分别从最左和最右端开始。
值得注意的是scanf
和printf
真的比cin
和cout
快很多,所以还是尽量练习着使用scanf
和printf
吧
状态转移方程
左端:如果l[i-1]>a[i]+sum -> l[i]=l[i-1],否则l[i]=a[i]+sum
右端:如果r[i+1]>a[i]+sum -> r[i]=r[i+1],否则r[i]=a[i]+sum
注意(1)i在移动过程中要考虑sum是否小于0;若sum小于0,要将sum置成0;在进行后面的运算。
代码如下:
#include <iostream>
#include <cstdio>
using namespace std;
const int MAX =50001;
int a[MAX],l[MAX],r[MAX];
int main()
{
int sum,max,n,k;
scanf("%d",&k);
while(k--){
scanf("%d",&n);
l[0]=-MAX; //左端
sum=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
if(l[i-1]>a[i]+sum)
l[i]=l[i-1];
else
l[i]=a[i]+sum;
sum+=a[i];
if(sum<0)
sum=0;}
r[n+1]=-MAX;//右端
sum=0;
max=-MAX;
for(int j=n;j!=0;j--){
if(r[j+1]>a[j]+sum)
r[j]=r[j+1];
else
r[j]=a[j]+sum;
sum+=a[j];
if(sum<0)
sum=0;
if(l[j]+r[j+1]>max)
max=l[j]+r[j+1];
}
printf("%d\n",max);
}
return 0;
}
Bessie is such a hard-working cow. In fact, she is so focused on maximizing her productivity that she decides to schedule her next N (1 ≤ N ≤ 1,000,000) hours (conveniently labeled 0..N-1) so that she produces as much milk as possible.
Farmer John has a list of M (1 ≤ M ≤ 1,000) possibly overlapping intervals in which he is available for milking. Each interval i has a starting hour (0 ≤ starting_houri ≤ N), an ending hour (starting_houri < ending_houri ≤ N), and a corresponding efficiency (1 ≤ efficiencyi ≤ 1,000,000) which indicates how many gallons of milk that he can get out of Bessie in that interval. Farmer John starts and stops milking at the beginning of the starting hour and ending hour, respectively. When being milked, Bessie must be milked through an entire interval.
Even Bessie has her limitations, though. After being milked during any interval, she must rest R (1 ≤ R ≤ N) hours before she can start milking again. Given Farmer Johns list of intervals, determine the maximum amount of milk that Bessie can produce in the N hours.
Input
* Line 1: Three space-separated integers: N, M, and R
* Lines 2..M+1: Line i+1 describes FJ's ith milking interval withthree space-separated integers: starting_houri , ending_houri , and efficiencyi
Output
* Line 1: The maximum number of gallons of milk that Bessie can product in the N hours
Sample Input
12 4 2
1 2 8
10 12 19
3 6 24
7 10 31
Sample Output
43
此题主要有N(时间长度),M(数据组数),R(休息时间)
开始时间、结束时间、得到的牛奶量。
(1)结构体定义每组的参数
(2)利用sort将每组的开始时间升序排列,方便取出
(3)对于结束时间和休息时间的处理,可以吧把休息时间加在结束时间的结尾处,方便开始下一次获取
条件:a[i].end<=a[i+1].start
状态转移方程
dp[i]=max(dp[i],dp[j]+a[i].value)
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
int dp[1001];
struct canshu{
int start;
int end;
int value;}a[1001];
bool cmp(canshu a,canshu b){
return a.start<b.start;
}
int main()
{
int N,M,R,i,j;
scanf("%d%d%d",&N,&M,&R);
for(i=1;i<=M;++i)
{
scanf("%d%d%d",&a[i].start,&a[i].end,&a[i].value);
a[i].end+=R;
}
stable_sort(a+1,a+M+1,cmp);
int maxsum;
maxsum=dp[1]=a[1].value;
for(i=2;i<=M;++i)
{
dp[i]=a[i].value;
for(j=i-1;j>0;--j)
{
if(a[i].start-a[j].end>=0)
{
dp[i]=max(dp[i],dp[j]+a[i].value);
}
}
maxsum=max(maxsum,dp[i]);
}
printf("%d\n",maxsum);
return 0;
}
Farmer John's cows would like to jump over the moon, just like the cows in their favorite nursery rhyme. Unfortunately, cows can not jump.
The local witch doctor has mixed up P (1 <= P <= 150,000) potions to aid the cows in their quest to jump. These potions must be administered exactly in the order they were created, though some may be skipped.
Each potion has a 'strength' (1 <= strength <= 500) that enhances the cows' jumping ability. Taking a potion during an odd time step increases the cows' jump; taking a potion during an even time step decreases the jump. Before taking any potions the cows' jumping ability is, of course, 0.
No potion can be taken twice, and once the cow has begun taking potions, one potion must be taken during each time step, starting at time 1. One or more potions may be skipped in each turn.
Determine which potions to take to get the highest jump.
Input
* Line 1: A single integer, P
* Lines 2..P+1: Each line contains a single integer that is the strength of a potion. Line 2 gives the strength of the first potion; line 3 gives the strength of the second potion; and so on.
Output
* Line 1: A single integer that is the maximum possible jump.
Sample Input
8
7
2
1
8
4
3
5
6
Sample Output
17
题意:奇数步加,偶数步减,可跳过,求最高
主要在于考虑以奇数步结尾还是以偶数步结尾,取两者的最大值
dp[0][i]
表示前i个数经过偶数次跳跃增加的最大能量值,dp[1][i]
表示前i个数经过奇数次跳跃增加的最大能量值,初始化dp[0][0] = 0
,状态转移方程为dp[0][i] = max(dp[0][i-1], dp[1][i-1] - a[i]),dp[1][i] = max(dp[1][i-1], dp[0][i-1] + a[i])
,最后输出dp[0][P]
和dp[1][P]
的最大值即可
#include <iostream>
#include <cstdio>
using namespace std;
const int MAX=150001;
int dp[2][MAX];
int a[MAX];
int main()
{
int p,i,j;
while(scanf("%d",&p)!=EOF){
for(i=1;i<=p;i++){
scanf("%d",&a[i]);}
for(j=0;j<MAX;j++){
dp[0][i]=dp[1][i]=-MAX;
}
for(j=1;j<=p;j++){
dp[1][j]=max(dp[1][j-1],dp[0][j-1]+a[j]);
dp[0][j]=max(dp[0][j-1],dp[1][j-1]-a[j]);
}
printf("%d\n",max(dp[0][p],dp[1][p]));
}
return 0;
}