专栏文章
题解:P7751 [COCI 2013/2014 #2] PUTNIK
P7751题解参与者 1已保存评论 1
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @miovq4x3
- 此快照首次捕获于
- 2025/12/03 01:56 3 个月前
- 此快照最后确认于
- 2025/12/03 01:56 3 个月前
1. 分析
下面的 dalao 们都用的搜索,我发现这道题可以维护一个连续的区间,而且每次向左或向右拓展,所以考虑区间 dp,暴力枚举两端节点(实际上和 dalao 们的思路差不多)。
2. dp 数组定义
表示两端城市是 和 时的最小飞行时间。
3. 细节
当我们遍历到左端点为 ,右端点为 的时候,不难得出下一个城市是 。
设下一个城市为 ,当 时,直接 continue(因为遍历完了),否则就直接考虑把 接到 前面或者 后面。
状态转移方程:
。
。
设下一个城市为 ,当 时,直接 continue(因为遍历完了),否则就直接考虑把 接到 前面或者 后面。
状态转移方程:
。
。
4. code
CPP#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
vector<vector<int>> t(n+1,vector<int>(n+1));//时间
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>t[i][j];
}
}
vector<vector<int>> dp(n+1,vector<int>(n+1,INT_MAX));//dp[i][j]表示两端城市是i和j时的最小飞行时间
dp[1][1]=0;//初始化
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(dp[i][j]==INT_MAX) continue;//不可达
int k=max(i,j)+1;//下一个城市
if(k>n) continue;//超出城市总数
dp[i][k]=min(dp[i][k],dp[i][j]+t[j][k]);//将k接在i左边
dp[k][j]=min(dp[k][j],dp[i][j]+t[i][k]);//将k接在j右边
}
}
int ans=INT_MAX;
for(int i=1;i<=n;i++){
ans=min(ans,dp[i][n]);//求出最少时间
ans=min(ans,dp[n][i]);
}
cout<<ans;
return 0;
}
时间复杂度 。
空间复杂度 。
空间复杂度 。
完结撒花,若有不足,请 dalao 们指出。
相关推荐
评论
共 1 条评论,欢迎与作者交流。
正在加载评论...