问题描述:
长江游艇俱乐部在长江上设置了n个游艇出租站1,2,…,n。游客可在这些游艇出租站租用游艇,并在下游的任何一个游艇出租站归还游艇。游艇出租站i到游艇出租站j之间的租金为r(i,j),1<=i<j<=n。试设计一个算法,计算出从游艇出租站1 到游艇出租站n所需的最少租金。
输入格式:
第1 行中有1 个正整数n(n<=200),表示有n个游艇出租站。接下来的第1到第n-1 行,第i行表示第i站到第i+1站,第i+2站, ... , 第n站的租金。
输出格式:
输出从游艇出租站1 到游艇出租站n所需的最少租金。
输入样例:
在这里给出一组输入。例如:
3
5 15
7
输出样例:
在这里给出相应的输出。例如:
12
解决方案:
1.三重循环/填表法:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
int m[200][200] = { 0 };
cin>>n;
for (int i = 1; i <= n - 1; i++){
for (int j = i + 1; j <= n; j++) cin>>m[i][j]; //m[i][j] is the cost from i to j
}
for (int r = 2; r <= n; r++){ //find the optimal solution the from <1,2> to <1,n>
for (int i = 1; i <= n - r + 1; i++){ //(n - r + 1) means the range depends on r
int j = i + r - 1; // make the distance from i to j is r
for (int k = i; k <= j; k++){ //k∈(i,j)→r(i,k)+r(k,j) min
int t = m[i][k] + m[k][j];
if (t < m[i][j]) m[i][j] = t; //replace the min
}
}
}
cout<< m[1][n] << endl;
return 0;
}
2.状态转移方程
#include<bits/stdc++.h>
using namespace std;
int r[200][200];
int getMinRent(int n){
int dp[200]; //令dp[i]为从出租站1到出租站n所需要的最少租金
dp[1]=0; //初始化 initialization
dp[2]=r[1][2]; //初始化 initialization
for(int i=3;i<=n;i++){
dp[i]=r[1][i]; //先初始化dp[i]为第1到i站的租金
for(int j=2;j<i;j++){
dp[i]=min(dp[i],dp[j]+r[j][i]); //状态转移方程
}
}
return dp[n];
}
int main(){
int n;
cin>>n;
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
cin>>r[i][j];
cout<<getMinRent(n);
return 0;
}