POJ 2181 Jumping Cows
//本题是用DP来解,大致意思是在偶数次时选择一个数为增大,
//在奇数次时选择一个数为减小,可以越过不选,问最后最大
//能积累多大的数。
//主要是状态转移方程:s[i][2][2]来表示在奇数、偶数和选择、不选四个
//状态,那么如果这一次为奇数选择,那么上一次必定是选 偶数选择 和 奇数
//不选 这两个状态中最大的于是有了: s[i][0][0]=max(s[i-1][0][1],s[i-1][1][0])-a[i];
//同理,其他三个方程也是这么写,清楚这一点,就OK了,还算比较简单
#include<iostream>
using namespace std;
int max(int a,int b)
{
return a>b?a:b;
}
int main()
{
int a[151000],s[151000][2][2],i,j,k,n;
scanf("%d",&n);
for(i=0;i<n;++i)
scanf("%d",&a[i]);
memset(s,0,sizeof(s[0][0][0]));
for(i=1;i<=n;++i)
{
s[i][0][0]=max(s[i-1][0][1],s[i-1][1][0])-a[i-1];
s[i][0][1]=max(s[i-1][0][1],s[i-1][1][0]);
s[i][1][0]=max(s[i-1][1][1],s[i-1][0][0])+a[i-1];
s[i][1][1]=max(s[i-1][1][1],s[i-1][0][0]);
}
printf("%d\n",max(max(s[n][0][0],s[n][0][1]),max(s[n][1][0],s[n][1][1])));
return 1;
}
using namespace std;
int max(int a,int b)
{
return a>b?a:b;
}
int main()
{
int a[151000],s[151000][2][2],i,j,k,n;
scanf("%d",&n);
for(i=0;i<n;++i)
scanf("%d",&a[i]);
memset(s,0,sizeof(s[0][0][0]));
for(i=1;i<=n;++i)
{
s[i][0][0]=max(s[i-1][0][1],s[i-1][1][0])-a[i-1];
s[i][0][1]=max(s[i-1][0][1],s[i-1][1][0]);
s[i][1][0]=max(s[i-1][1][1],s[i-1][0][0])+a[i-1];
s[i][1][1]=max(s[i-1][1][1],s[i-1][0][0]);
}
printf("%d\n",max(max(s[n][0][0],s[n][0][1]),max(s[n][1][0],s[n][1][1])));
return 1;
}