1. 程式人生 > >01 背包基礎 - 空間優化 (滾動數組,一維陣列)

01 背包基礎 - 空間優化 (滾動數組,一維陣列)

pac 使用 dp2 -1 col date for png logs

2017-09-03 11:39:16

writer:pprp

以很簡單的一個動態規劃問題為引入:

從左上角到右下角走過的路徑和最大,問你最大為多少?

1、可以想到普通的dp

狀態轉移為: dp[i][j] = max(dp[i-1][j],dp[i][j-1]) + arr[i][j];

2、采用滾動數組的方式-節約了不必要的空間

狀態轉移為:dp2[i%2][j] = max(dp2[(i+1)%2][j],dp2[i%2][j-1]) + arr[i][j];

3、采用一維陣列的方式更加節省空間

狀態轉移為:dp3[j] = max(dp3[j],dp3[j-1]) + arr[i][j];

圖解:

技術分享

代碼如下:

/*
@theme:空間優化,滾動數組,只使用一維陣列
@writer:pprp
@begin:10:45
@end:11:36
@declare:從左上角到右下角的總和最多為多少?
@error:
@date:2017/9/3
*/

#include <bits/stdc++.h>

using namespace std;
const int maxn = 100;
int arr[maxn][maxn];
int dp[maxn][maxn];
int dp2[2][maxn];
int dp3[maxn];
int n, m;

void init()
{
    freopen(
"in.txt","r",stdin); memset(dp,0,sizeof(dp)); memset(arr,0,sizeof(arr)); memset(dp2,0,sizeof(dp2)); memset(dp3,0,sizeof(dp3)); cin >> n >> m; for(int i = 0 ; i < n; i++) { for(int j = 0 ; j < m ; j++) { cin >> arr[i][j]; } } }
//普通簡單dp int fun1() { dp[0][0] = arr[0][0]; for(int i = 1; i < n ; i++) { dp[i][0] += arr[i][0] + dp[i-1][0]; } for(int j = 1; j < m ; j++) { dp[0][j] += arr[0][j] + dp[0][j-1]; } for(int i = 0 ; i < n ; i++) { for(int j = 0 ; j < m ; j++) { dp[i][j] = max(dp[i-1][j],dp[i][j-1]) + arr[i][j]; } } return dp[n-1][m-1]; } //滾動數組 int fun2() { dp2[0][0] = arr[0][0]; for(int i = 1 ; i < m ; i++) dp2[0][i] += dp2[0][i-1] + arr[0][i]; for(int i = 0 ; i < n ; i++) { for(int j = 0 ; j < m ; j++) { dp2[i%2][j] = max(dp2[(i+1)%2][j],dp2[i%2][j-1]) + arr[i][j]; } } return dp2[(n-1)%2][m-1]; } //一維陣列 int fun3() { for(int i = 0 ; i < n ; i++) { dp3[0] = arr[i][0]; for(int j = 1 ; j < m ; j++) { dp3[j] = max(dp3[j],dp3[j-1]) + arr[i][j]; } } return dp3[m-1]; } int main() { init(); cout << fun1() << endl; cout << "-----" << endl; for(int i = 0 ; i < n ; i++) { for(int j = 0 ; j < m ; j++) cout << dp[i][j] << " "; cout << endl; } cout << endl; cout << fun2() << endl; cout << "-----" << endl; for(int i = 0 ; i < m ; i++) { cout << dp2[0][i] << " "; } cout << endl; for(int i = 0 ; i < m ; i++) { cout << dp2[1][i] << " "; } cout << endl; cout << "-----" << endl; cout << fun3() << endl; return 0; }

01 背包基礎 - 空間優化 (滾動數組,一維陣列)