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 ;
}

 

 

你可能感兴趣的:(ping)