题目要求
思路
这个题和那个洛谷的“高手去爬山”很像,那个是已知就几条边有权重,这个输入的是个半矩阵,而且数据量小于200,其实挺大的,不能用深搜了
错误想法
求最少租金,最小值,考虑dp,从出租站1到出租站n所需最少租金,这个就是区间dp的问法啊,合并石子那道区间dp题,求从第一堆到最后一堆合并石子所需要的最小力气,也相当于板子题了,但这个是求最小价值,区间类一般用于合并类问题(石子合并,矩阵连乘)
for三重循环,区间长度,左端点,划分点
再想:从1->n, 求最短,不就是单源最短路,用dijstra算法!
再想: 线性dp:dp[j]表示到j站的最小价格,和最长上升子序列有点像,第j站已经固定,但不确定上一站有没有
代码
动态规划
- 化零为整
dp[j]表示从第1站到第j站的最小租金,属性:最小值 - 化整为零
可能是从第1站直接到第j站,也可能是中间经过了第k站,再到第j站(很像最长上升子序列)
即
dp[j] = min(dp[k] + w[k][j], dp[j])
#include<bits/stdc++.h>
using namespace std;
const int N = 210;
int f[N];
int a[N][N];
int main()
{
int n;
cin >> n;
//讨论一下读入 1-2 1-3 2 - 3, 相当于是上三角形,不一定要按照她给的输入
for(int i = 1; i <= n; i++)
{
for(int j =i + 1; j <= n; j++)
{
cin >> a[i][j];
}
}
for(int i = 2; i <= n; i++)
{
f[i] = a[1][i]; //初始化,从第一站,到任意一站
}
// //测试读入是否正确
// for(int i = 1; i <= n; i++)
// {
// for(int j = 1; j <= n; j++)
// cout << a[i][j]<<" ";
// cout<<endl;
// }
for(int len = 1; len <= n; len++) //区间长度
{
int j = 1 + len - 1;
for(int k = 2; k < j; k++)
{
f[j] = min(f[j], f[k] + a[k][j]);
}
}
cout<<f[n]<<endl;
return 0;
}
Dijkstra
等主播学完图论再补充