華爲筆試——C++平安果dp算法

 題目:平安果ios

題目介紹:給出一個m*n的格子,每一個格子裏有必定數量的平安果,如今要求從左上角頂點(1,1)出發,每次走一格並拿走那一格的全部平安果,且只能向下或向右前進,最終到達右下角頂點(m,n),要求求出能拿走的平安果的最大數值。算法

輸入:第一行有兩個數值m,n,而後是m行n列數值。spa

輸出:一個數值表明平安果的最大數量。code

例:blog

輸入:ci

4 4io

1 2 4 8class

10 14 3 9stream

17 6 7 20im

12 5 21 23

輸出:

89

分析:這是一種比較典型的dp算法(動態規劃)的題目,每一格獲取的平安果最大數值都與上格或左格有關(即交疊問題),且無後效性。這題也證實了動態規劃能夠解決貪心算法所解決不了的問題,若用貪心算法,不必定能得出整體最優解。

狀態方程:dp[ i ][ j ]=max{ dp[ i-1 ][ j ] , dp[ i ][ j-1 ]}+A[ i ][ j ] 

代碼以下:

 1 #include <vector>
 2 #include <iostream>
 3 using namespace std;
 4 int main()
 5 {
 6     int m, n;
 7     int i, j;
 8     while (cin >> m >> n)
 9     {
10         vector<vector<int>> ivec(m, vector<int>(n));
11         for (i = 0; i < m; ++i)
12         {
13             for (j = 0; j < n; ++j)
14             {
15                 cin >> ivec[i][j];
16             }
17         }
18         vector<vector<int>> dp(ivec);
19         for (i = 1; i < m; ++i)
20         {
21             dp[i][0] += dp[i - 1][0];
22         }
23         for (j = 1; j < n; ++j)
24         {
25             dp[0][j] += dp[0][j - 1];
26         }
27         for (i = 1; i < m; ++i)
28         {
29             for (j = 1; j < n; ++j)
30             {
31                 dp[i][j] += (dp[i - 1][j] < dp[i][j - 1]) ? dp[i][j - 1] : dp[i - 1][j];
32             }
33         }
34         cout << dp[m - 1][n - 1] << endl;
35     }
36     return 0;
37 }

結果以下圖所示:

相關文章
相關標籤/搜索