UPC-籃球運動(線性DP)

籃球運動

時間限制: 1 Sec 內存限制: 128 MB
[提交] [狀態]
題目描述
小明建造了一個籃球場,他請來了2行n列的人,想讓他們進行比賽。每一個人都有一個能力值,第一行分別爲h11,h12,…,h1n,第二行爲h21,h22,…,h2n。現在小明可以選一些人組成一個最強團隊。但是選人是有規則的,因爲選一個人會讓附近的人都很妒忌,所以他既不會同一行裏連續選擇2個人,也不會同一列裏的連續選擇2個人。
現在他希望所選團隊的能力值的之和最大,但人太多了,所以他想請聰明的你幫他解決這個問題。解決在滿足規則的情況下能力值的和最大爲多少?

輸入
第一行輸入一個整數n(1≤n≤105),表示每行中的學生人數。
第二行輸入n個整數h[1,1],h[1,2],…,h[1,n](1≤h[1,i]≤109),其中h[1,i]表示第一行中的第i個學生能力值。
第三行輸入n個整數h[2,1],h[2,2],…,h[2,n](1≤h[2,i]≤109),其中h[2,i]表示第二行中的第i個學生能力值。
輸出
輸出一個整數,表示所選團隊中能力值之和最大。
樣例輸入 Copy
【樣例1】
5
9 3 5 7 3
5 8 1 4 5
【樣例2】
3
1 2 9
10 1 1
【樣例3】
1
7
4
樣例輸出 Copy
【樣例1】
29
【樣例2】
19
【樣例3】
7
提示
樣例1說明:小明可以選擇以下團隊:9,8,7,5.
樣例2說明:小明可以選擇以下團隊

在這裏插入圖片描述
思路:
想到了dp但是比賽時用一維推了好久沒推出來
中午看到大佬博客又想起了光光說過“dp推不出來可以先增加維數”
所以還是很好推的

dp[i][j]表示只從前i箇中選且該列的狀態爲j的最大值
j=0表示前一列中哪個都不選
j=1表示前一列中選第一行的,這一列只能選第二行的
j=2表示前一列中選第二行的,這一列只能選第一行的

狀態轉移方程如下:

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

代碼:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline void read(ll &x){
   ll s = 0, w = 1; char ch = getchar();
   while(ch < '0' || ch > '9'){ if(ch == '-') w = -1; ch = getchar(); }
   while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
   x = s*w;
}
const int maxn=1e5+150;
ll dp[maxn][3];
int n;
ll a[3][maxn];
void AC(){
    cin>>n;
    for(int i=1;i<=2;i++)
        for(int j=1;j<=n;j++)
            read(a[i][j]);
    dp[1][1]=a[1][1],dp[1][2]=a[2][1];
    for(int i=2;i<=n;i++){
        dp[i][0]=max(dp[i-1][1],dp[i-1][2]);
        dp[i][1]=max(dp[i-1][2],dp[i-1][0])+a[1][i];
        dp[i][2]=max(dp[i-1][0],dp[i-1][1])+a[2][i];
    }
    cout<<max(dp[n][0],max(dp[n][1],dp[n][2]));
}
int main(){
    AC();
    return 0;
}

ps:記得數組不要越界

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章