Codeforces 358D Dima and Hares:dp【只考虑相邻元素】

题目链接:http://codeforces.com/problemset/problem/358/D

题意:

  有n个物品A[i]摆成一排,你要按照某一个顺序将它们全部取走。

  其中,取走A[i]的收益为:

    (1)若A[i-1]和A[i+1]都没被取走,则收益为a[i]

    (2)若A[i-1]和A[i+1]被取走了一个,则收益为b[i]

    (3)若A[i-1]和A[i+1]都被取走,则收益为c[i]

    注:将A[1]的左边和A[n]的右边视为永远有一个取不走的物品。

  问你最大收益是多少。

题解:

  表示状态:

    dp[i][0/1] = max wealth

    表示A[i]比A[i-1]先取(0)或后取(1),此时取走A[1 to i-1]的最大收益。

  找出答案:

    ans = dp[n+1][1]

    因为可以看做A[n]右边有一个不取走的物品

    所以dp[n+1][1]对应的就是将所有物品取走的最大获益

  如何转移:

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

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

    根据A[i-1]的左右情况,加上对应的取走A[i-1]的获利,即为当前的总获利。

  边界条件:

    dp[1][0] = 0

    dp[1][1] = -INF 

    因为将A[1]左边看作有一个物体,所以只能是A[1]先选,当前总获利为0。

AC Code:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #define MAX_N 3005
 5 #define INF 1000000000
 6 
 7 using namespace std;
 8 
 9 int n;
10 int a[MAX_N];
11 int b[MAX_N];
12 int c[MAX_N];
13 int dp[MAX_N][2];
14 
15 void read()
16 {
17     cin>>n;
18     for(int i=1;i<=n;i++) cin>>a[i];
19     for(int i=1;i<=n;i++) cin>>b[i];
20     for(int i=1;i<=n;i++) cin>>c[i];
21 }
22 
23 void work()
24 {
25     dp[1][0]=0;
26     dp[1][1]=-INF;
27     for(int i=2;i<=n+1;i++)
28     {
29         dp[i][0]=max(dp[i-1][0]+b[i-1],dp[i-1][1]+c[i-1]);
30         dp[i][1]=max(dp[i-1][0]+a[i-1],dp[i-1][1]+b[i-1]);
31     }
32     cout<<dp[n+1][1]<<endl;
33 }
34 
35 int main()
36 {
37     read();
38     work();
39 }
原文地址:https://www.cnblogs.com/Leohh/p/8259984.html