长江游艇俱乐部在长江上设置了 n n n 个游艇出租站 1 , 2 , … … , n 1,2,……,n 1,2,……,n。游客可在这些游艇出租站租用游艇,并在下游的任何一个游艇出租站归还游艇。游艇出租站i到游艇出租站 j j j 之间的租金为 r ( i , j ) , 1 < = i < j < = n r(i,j),1<=i
输入格式:第 1 1 1 行中有 1 1 1 个正整数 n ( n < = 200 ) n(n<=200) n(n<=200),表示有 n n n 个游艇出租站。接下来的第 1 1 1 到第 n − 1 n-1 n−1 行,第 i i i 行表示第 i i i 站到第 i + 1 i+1 i+1 站、第 i + 2 i+2 i+2 站、 … 、第 n n n 站的租金。
输出格式:输出从游艇出租站 1 1 1 到游艇出租站 n n n 所需的最少租金。
输入样例:
3
5 15
7
输出样例:
12
1. 本题采用动态规划思路来解决,需要写出递归方程。
2. 本题的思路和矩阵链相乘思路很相似,但递推方程不一样。租用游艇:比如从 1 1 1 到 3 3 3,然后从 3 3 3 到 n n n ;矩阵链:比如从 1 1 1 到 3 3 3,那么接下来就是 4 4 4 到 n n n。
3. 思路:中间位置划分:i -> k ->j
。即分为 r[i][j] -> r[i][k] + r[k][j]
。由于是最少租金,初始时 dp[i][j] = r[i][j]
。状态转移方程为 dp[i][j] = min(dp[i][k] + dp[k][j]), k = [i+1 , j-1]
。
时间复杂度 O ( n 3 ) O(n^3) O(n3)
#include
using namespace std;
int main()
{
int n, r[300][300], dp[300][300];
cin >> n;
for(int i = 1; i <= n; i++) //出租站i到i的租金为0
{
r[i][i] = dp[i][i] = 0;
}
for(int i = 1; i <= n - 1; i++) //输入出租站i到i+1的租金
{
for(int j = i + 1; j <= n; j++){
cin >> r[i][j];
dp[i][j] = r[i][j];
}
}
for(int i = 1; i <= n - 1; i++)
{
for(int j = i + 1; j <= n; j++)
{
for(int k = i + 1; k <= j - 1; k++)
{
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j]);
}
}
}
cout << dp[1][n];
return 0;
}
1. 由于Dijkstra算法用于最短距离,所以这里我们用距离代替租金(本质是一样的)。
2. 先用一个 d i s [ j ] dis[j] dis[j] 来存储站 1 1 1 到站 2 2 2,站 3 3 3 … 站 n n n 的最短距离,刚开始 d i s dis dis 的初始距离就是 r [ 1 ] [ j ] r[1][j] r[1][j] 的距离。
3. 之后我们遍历查找确定其他的最小距离。因为前面 1 1 1, 2 2 2 已经确认所以我们从 i=3
开始, j j j 从确定好的里面进行挑选,当 dis[i]>dis[j]+r[j][i]
时进行更新。最后输出 d i s [ n ] dis[n] dis[n]。
时间复杂度 O ( n 2 ) O(n^2) O(n2)
#include
using namespace std;
//这里用距离代替租金
int main()
{
int n;
cin >> n;
int r[n][n], dis[n];
for(int i = 1; i <= n; i++) //出租站i到i的距离为0
{
r[i][i] = 0;
}
for(int i = 1; i <= n - 1; i++) //输入出租站i到i+1的距离
{
for(int j = i + 1; j <= n; j++){
cin >> r[i][j];
}
}
dis[0] = dis[1] = 0;
for(int j = 2; j <= n; j++)
{
dis[j] = r[1][j]; //dis的初始距离就是r[1][j]的距离
}
for(int i = 3; i <= n; i++)
{
for(int j = 1; j <= i-1 ; j++)
{
if(dis[i] > dis[j] + r[j][i])
{
dis[i] = dis[j] + r[j][i];
}
}
}
cout << dis[n];
return 0;
}