[洛谷1359] 租用游艇

    xiaoxiao2021-12-14  43

    题目描述

    长江游艇俱乐部在长江上设置了n 个游艇出租站1,2,…,n。游客可在这些游艇出租站租用游艇,并在下游的任何一个游艇出租站归还游艇。游艇出租站i 到游艇出租站j 之间的租金为r(i,j),1<=i<=j<=n。试设计一个算法,计算出从游艇出租站1 到游艇出租站n 所需的最少租金。 对于给定的游艇出租站i 到游艇出租站j 之间的租金为r(i,j),1<=i<j<=n,编程计算从游艇出租站1 到游艇出租站n所需的最少租金。 保证计算过程中任何时刻数值都不超过10^6

    输入格式

    由文件提供输入数据。文件的第1 行中有1 个正整数n(n<=200),表示有n个游艇出租站。接下来的n-1 行是一个半矩阵r(i,j),1<=i

    输出格式

    程序运行结束时,将计算出的从游艇出租站1 到游艇出租站n所需的最少租金输出到文件中。

    样例输入

    3 5 15 7

    样例输出

    12

    题目分析

    赤裸裸的最短路,模板秒过。 当然这题因为有序,因此可以直接动规

    源代码

    最短路 #include<algorithm> #include<iostream> #include<iomanip> #include<cstring> #include<cstdlib> #include<vector> #include<cstdio> #include<cmath> #include<queue> using namespace std; inline const int Get_Int() { int num=0,bj=1; char x=getchar(); while(x<'0'||x>'9') { if(x=='-')bj=-1; x=getchar(); } while(x>='0'&&x<='9') { num=num*10+x-'0'; x=getchar(); } return num*bj; } const int maxn=20005; struct Edge { int from,to,dist; }; struct Spfa { int n,m; vector<Edge>edges; vector<int>G[maxn]; bool inque[maxn]; int dist[maxn],used[maxn],path[maxn]; void init(int n) { this->n=n; edges.clear(); for(int i=1; i<=n; i++)G[i].clear(); } void AddEdge(int from,int to,int dist) { edges.push_back((Edge) { from,to,dist }); m=edges.size(); G[from].push_back(m-1); } bool main(int s) { for(int i=1; i<=n; i++)dist[i]=0x7fffffff/2; memset(inque,0,sizeof(inque)); deque<int>Q; Q.push_back(s); dist[s]=0; path[s]=s; inque[s]=1; used[s]++; while(!Q.empty()) { int Now=Q.front(); Q.pop_front(); inque[Now]=0; for(int i=0; i<G[Now].size(); i++) { Edge& e=edges[G[Now][i]]; int Next=e.to; if(dist[Next]>dist[Now]+e.dist) { dist[Next]=dist[Now]+e.dist; path[Next]=Now; if(!inque[Next]) { used[Next]++; if(used[Next]==edges.size())return false; //负权回环 if(!Q.empty()&&dist[Next]<dist[Q.front()])Q.push_front(Next); //SLF优化 else Q.push_back(Next); inque[Next]=1; } } } } return true; } void Output(int x) { if(path[x]==x) { cout<<x<<" "; return; } Output(path[x]); cout<<x<<" "; } }; Spfa spfa; int n; int main() { n=Get_Int(); spfa.init(n); for(int i=1; i<n; i++) for(int j=i+1; j<=n; j++) { int v=Get_Int(); spfa.AddEdge(i,j,v); } spfa.main(1); printf("%d\n",spfa.dist[n]); return 0; }动规 #include<algorithm> #include<iostream> #include<iomanip> #include<cstring> #include<cstdlib> #include<vector> #include<cstdio> #include<cmath> #include<queue> using namespace std; inline const int Get_Int() { int num=0,bj=1; char x=getchar(); while(x<'0'||x>'9') { if(x=='-')bj=-1; x=getchar(); } while(x>='0'&&x<='9') { num=num*10+x-'0'; x=getchar(); } return num*bj; } int n,map[205][205],f[205]; int main() { //动态规划解法 n=Get_Int(); memset(f,0x7f,sizeof(f)); f[1]=0; for(int i=1; i<n; i++) for(int j=i+1; j<=n; j++) map[i][j]=Get_Int(); for(int i=2; i<=n; i++) for(int j=1; j<i; j++) f[i]=min(f[i],f[j]+map[j][i]); printf("%d\n",f[n]); return 0; }
    转载请注明原文地址: https://ju.6miu.com/read-970163.html

    最新回复(0)