代码改变世界

codeforce 358D - Dima and Hares 动态规划

2013-11-20 00:02  凝月流风  阅读(375)  评论(0编辑  收藏  举报

   一开始看到题目以为是最大能量项链一样的动规问题,但按照那种划分的话情况非常混乱,而且时间复杂度很大,所以行不通

    因为某只hare的joy只有周围两只是否feed相关,所以可把n只hare的最大值分解为前n-1只1)在第n只之后feed的最大值 2)在第n只之前feed的最大值  再加上第n只对应的值。 因为前n-2只与第n只毫无关系,所以可以当做把他们先喂完。 然后再以此往前类推即可。 然后将递归转化为从头开始递推就可以了,,所以只要求出在第k项在第k+1项后feed时前面k项的最大值以及第k项在第k+1项之前feed时的最大值即可。

   状态转移方程为 :

dp[i][0] = max(dp[i-1][1]+c[i], dp[i-1][0]+b[i]);
dp[i][1] = max(dp[i-1][1]+b[i], dp[i-1][0]+a[i]);

只需求到第n-1项,即可求出最大值    M = max(dp[i-1][0]+a[i], dp[i-1][1]+b[i]);

PS.要将n=1的情况单独考虑~

代码如下:

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 3010;
int a[maxn], b[maxn], c[maxn];
long long dp[maxn][2];
int main()
{
    int n, i, j;
    long long M;
    scanf("%d", &n); 
    for (i = 0; i < n; i++)
      scanf("%d", &a[i]);
    for (i = 0; i < n; i++)
      scanf("%d", &b[i]);
    for (i = 0; i < n; i++)
      scanf("%d", &c[i]);
  if (n == 1)
      M = a[0];
    else { 
  dp[0][0] = b[0];
  dp[0][1] = a[0];
  for (i = 1; i < n-1; i++) {
      dp[i][0] = max(dp[i-1][1]+c[i], dp[i-1][0]+b[i]);
      dp[i][1] = max(dp[i-1][1]+b[i], dp[i-1][0]+a[i]);
    }
    M = max(dp[i-1][0]+a[i], dp[i-1][1]+b[i]);
  }
    cout << M << endl;
  return 0;
}