咳咳 以下均为原创,发散乱想
好吧,一张图片说明完毕,我们用路径长短表示坐船费用,求最少费用:
ps:本题属于最短路线求解。发散:可以将路径长短通过 线性映射或 非线性映射转化为某种(加权)量,来求解最优(加权)问题。ok,这就看你的脑容量有多大了!
分析:1.话说动态规划两要素:下一阶段的最优状态=现阶段最优状态+当前决策 (这是从自底向上的角度出发思考的,对应着最优递归关系式)
2.需要个关键技巧:合适的定义一种最优状态表来记录最优状态值,本题我们用m[i][j]表示i站到j站的最少费用,m[i][j]就是我们要找的最优状态表(本题中它属于二维表)
3.必须利用题目信息,该信息是决策用到的依据。本文用p[i][j]表示i站直接到j站的费用,i的取值范围(0,n-1),j的取值范围(1,n)。
仔细分析最优子结构,根据问题内容科学写出最优递归关系式。
代码:
1 // 2 // 3 4 #include "stdafx.h" 5 #include <iostream> 6 using namespace std; 7 8 class mincost_chuanfei { 9 public: 10 int n; 11 int **p, **m,**t; 12 13 void data_read() 14 { 15 int i, j; 16 cin >> n; 17 p = new int*[n]; 18 for (i = 0; i < n; i++) p[i] = new int[n+1];//p[i][j]表示i站直接到j站的费用,i@(0,n-1),j@(1,n) 19 m = new int*[n]; 20 for (i = 0; i < n; i++) m[i] = new int[n+1];//m[i][j]表示i站到j站的最少费用 21 t = new int*[n]; 22 for (i = 0; i < n; i++) t[i] = new int[n+1];//t[i][j]用于跟踪i站到j站之间断开的某一站序号,用于构造最优解 23 for (i = 0; i < n; i++) 24 { 25 for (j = i + 1; j <= n; j++) cin >> p[i][j]; 26 } 27 } 28 29 void data_processing() 30 { 31 int i, j, s,tmp; 32 for (s = 1; s<=n; s++)//让步距s从1加大到n 33 { 34 for (i = 0; i<=n - s; i++)//i@(0,n-s) 35 { 36 j = s + i;//j等于i+步距s 37 if (s == 1) { m[i][j] = p[i][j]; t[i][j] = j; } 38 else { 39 tmp = p[i][j]; t[i][j] = j; 40 for (int k = i + 1; k < j; k++) 41 { 42 if (m[i][k] + m[k][j] < tmp) { tmp = m[i][k] + m[k][j]; t[i][j]=k;} 43 } 44 m[i][j] = tmp; 45 46 } 47 } 48 } 49 50 } 51 52 void Traceback(int i, int j, int** t) 53 { 54 if (t[i][j] == j) { 55 cout << "start:"<<i<<" end:"<<j << endl; return; 56 } 57 Traceback(i, t[i][j], t); 58 Traceback(t[i][j], j, t); 59 } 60 61 62 63 void data_output() 64 { 65 cout << "the min cost:" << m[0][n] << endl; 66 Traceback(0, n, t); 67 68 } 69 }; 70 71 72 73 74 int main() 75 { 76 mincost_chuanfei dd; 77 dd.data_read(); 78 dd.data_processing(); 79 dd.data_output(); 80 81 82 return 0; 83 }