Codeforces 358D Dima and Hares:dp【只考慮相鄰元素】

Leohh發表於2018-01-10

題目連結: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 }

 

相關文章