e878 - Q2 得分高手
題目描述
題目給定一個 n x m 的矩陣,矩陣中的每個元素代表一個分數。要求從左上角 (0, 0) 到右下角 (n-1, m-1) 的路徑,每次只能向右或向下移動,使得路徑上的分數總和最大。
解題思路
本題可以使用動態規劃 (Dynamic Programming) 解決。定義 dp[i][j] 為從 (0, 0) 到 (i, j) 的最大分數總和。
初始化 dp[0][0] = a[0][0]。
對於每個 (i, j),如果 i > 0,則 dp[i][j] = max(dp[i-1][j] + a[i][j], dp[i][j]),表示從上方移動到 (i, j)。
如果 j > 0,則 dp[i][j] = max(dp[i][j-1] + a[i][j], dp[i][j]),表示從左方移動到 (i, j)。
最後,dp[n-1][m-1] 就是從 (0, 0) 到 (n-1, m-1) 的最大分數總和。
程式碼中,從 (n-1, m-1) 反向填充 dp 表格,可以節省空間。
複雜度分析
- 時間複雜度: O(n*m)
- 空間複雜度: O(n*m)
程式碼
#include <iostream>
using namespace std;
int dp[3005][3005],a[3005][3005],n,m,ans;
int main(){
cin.tie(0); ios::sync_with_stdio(false);
cin >> n >> m;
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
cin >> a[i][j];
}
}
for(int i=n-1;i>=0;--i){
for(int j=m-1;j>=0;--j){
dp[i][j]=a[i][j];
if(i!=n-1){
dp[i][j]=max(dp[i+1][j]+a[i][j],dp[i][j]);
}
if(j!=m-1){
dp[i][j]=max(dp[i][j+1]+a[i][j],dp[i][j]);
}
ans=max(dp[i][j],ans);
}
}
cout << ans;
}