POJ1163 数学三角求最大路径

描述:
输入,行数,之后接数据,第一行一个数据,之后每行加一。
5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5

思路:
简单动态规划问题。
dp[i][j]定义为到这个数为止(包括这个数)的最大和,则:
dp[i][j] = max(d[i-1][j-1], d[i-1][j]),未考虑边界条件。
则用滚动数组得:

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main()
 5 {
 6       int n, more, ret;
 7       cin >> n;
 8       int* arr = new int[n];
 9       int* new_arr = new int[n]();
10       bool flag = true;
11 
12       for (int i = 1; i <= n; ++i) {
13           for (int j = 0; j < i; ++j) {
14               if (j == 0) {
15                   cin >> more;
16                   if (flag)
17                     new_arr[j] = arr[j] + more;
18                   else
19                     arr[j] = new_arr[j] + more;
20               } else if (j == i - 1) {
21                   cin >> more;
22                   if (flag)
23                     new_arr[j] = arr[j - 1] + more;
24                   else
25                     arr[j] = new_arr[j - 1] + more;
26               } else {
27                   cin >> more;
28                   if (flag)
29                     new_arr[j] = max(arr[j - 1], arr[j]) + more;
30                   else
31                     arr[j] = max(new_arr[j - 1], new_arr[j]) + more;
32               }
33           }
34           flag = !flag;
35       }
36 
37       ret = arr[0];
38       if (!flag) {
39           int* d = arr;
40           delete []d;
41           arr = new_arr;
42       }
43       for (int i = 1; i < n; ++i) {
44           if (ret < arr[i])
45               ret = arr[i];
46       }
47       delete []arr;
48       cout << ret;
49 }
View Code

再优化下空间:

考虑到每个数的更新,仅和上个数以及前一个数有关,可用一个变量保存前一个数,得:

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main() {
 5     int n, more, ret;
 6     cin >> n;
 7     int* arr = new int[n]();
 8 
 9     for (int i = 1; i <= n; ++i) {
10         int back = 0;
11         for (int j = 0; j < i; ++j) {
12             if (j == 0) {
13                 cin >> more;
14                 back = arr[j];
15                 arr[j] = arr[j] + more;
16             } else if (j == i - 1) {
17                 cin >> more;
18                 arr[j] = back + more;
19             } else {
20                 cin >> more;
21                 int sa = arr[j];
22                 arr[j] = max(back, arr[j]) + more;
23                 back = sa;
24             }
25         }
26     }
27 
28     ret = arr[0];
29     for (int i = 1; i < n; ++i) {
30         if (ret < arr[i])
31             ret = arr[i];
32     }
33     delete []arr;
34     cout << ret;
35     return 0;
36 }
View Code

 


虽然还有些可以优化,但时间和空间复杂度不变,若输入n行,则时间复杂度为O(n^2),空间复杂度为O(n)。

注意由于输入n行,则输入个数为n^2规模,所以n^2是时间复杂度下限。

posted on 2017-12-19 15:09  willaty  阅读(264)  评论(0编辑  收藏  举报

导航