DP练习1题解B
先上题目描述 POJ2181
样例输入
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<iostream>
#include<cstring>
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<<u[n]<<endl;
}
以上