DP练习1题解B

DP练习1题解B

先上题目描述 POJ2181

DP练习1题解B_第1张图片

样例输入
8
7
2
1
8
4
3
5
6

样例输出

17

因为有两个方向 如果只开一个数组dp[i],难以存储前一步是上还是下
而考虑到只要奶牛不是傻子(其实是人不是傻子) 最后一步一定是上
那么容易想到是不是可以用dp[i]存储到当前最大的跳跃能量(最后一步为上)

那么需要考虑就是下的那步 从dp[j]转移到dp[i],下的一步应该是i到j的最小值
那就要开一个数组预处理 但看到150000我们知道只有O(n)才能救中国 肯定不行

因为之前的思路问题在无法处理下的那步状态 那么换个角度可以想到开两个数组
一个存储当前步为下的最优子状态,一个存储当前步为上的最优子状态。
我把它们命名为u[ ] d[ ]
得到状态转移方程:
u[i]=max(d[i-1]+a[i],u[i-1])
d[i]=max(u[i-1]+a[i],d[i-1])

众所周知 状态转移方程出来 题目就做完了 因此

代码如下:

#include
#include
int u[150001];
int d[150001];
int a[150001];
using namespace std;
int main()
{
 int n,i;
 memset(a,0,sizeof(a));
 memset(d,0,sizeof(d));
 memset(u,0,sizeof(u));
 cin>>n;
 cin>>a[1];
 cin>>a[2];
 d[2]=a[1]-a[2];
 u[2]=a[1];
 if (a[2]>u[2]) u[2]=a[2];
 for (i=3;i<=n;i++)
 {
  cin>>a[i];
  u[i]=u[i-1];
  d[i]=d[i-1];
  if (d[i-1]+a[i]>u[i]) u[i]=d[i-1]+a[i];
  if (u[i-1]-a[i]>d[i]) d[i]=u[i-1]-a[i];
 }
 cout<

以上

你可能感兴趣的:(周六练习)