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]),未考虑边界条件。
则用滚动数组得:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
再优化下空间:
考虑到每个数的更新,仅和上个数以及前一个数有关,可用一个变量保存前一个数,得:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
虽然还有些可以优化,但时间和空间复杂度不变,若输入n行,则时间复杂度为O(n^2),空间复杂度为O(n)。
注意由于输入n行,则输入个数为n^2规模,所以n^2是时间复杂度下限。
【本文章出自博客园willaty,转载请注明作者出处,误差欢迎指出~】