Problem A. 晴天小猪历险记之Hill
时间限制 1000 ms
内存限制 128 MB
题目描述
这一天,他来到了一座深山的山脚下,因为只有这座深山中的一位隐者才知道这种药草的所在。但是上山的路错综复杂,由于小小猪的病情,晴天小猪想找一条需时最少的路到达山顶,但现在它一头雾水,所以向你求助。
山用一个三角形表示,从山顶依次向下有1段、2段、3段等山路,每一段用一个数字T(1< =T< =100)表示,代表晴天小猪在这一段山路上需要爬的时间,每一次它都可以朝左、右、左上、右上四个方向走(注意 :在任意一层的第一段也可以走到本层的最后一段或上一层的最后一段)。
晴天小猪从山的左下角出发,目的地为山顶,即隐者的小屋。
输入数据
第一行有一个数n(2<n<1000) ,n 表示山的高度。
从第二行至第 n+1 行,第 i+1 行有 i 个数,每个数表示晴天小猪在这一段山路上需要爬的时间。
输出数据
一个数,即晴天小猪所需要的最短时间。
样例输入
5
1
2 3
4 5 6
10 1 7 8
1 1 4 5 6
样例输出
10
感觉题目不是很完善,测试样例里应该包含了 每一层的最后一段能到达第一段或者上一层的第一段。
代码:
cpp
#include <bits/stdc++.h>
using namespace std;
using pii=pair<int,int>;
using ll=long long;
const int INF=1e9;
struct Node
{
int r,c;
int d;
bool operator<(Node const& other)const
{
return d>other.d;//for min-heap
}
};
int main()
{
int n;
cin>>n;
vector<vector<int>> T(n+1);
for(int r=1;r<=n;r++)
{
T[r].resize(r+1);
for(int c=1;c<=r;c++)
{
cin>>T[r][c];
}
}
vector<vector<int>>dist(n+1);
for(int r=1;r<=n;r++)
{
dist[r].assign(r+1,INF);//r+1长度,填充inf值
}
dist[n][1]=T[n][1];
priority_queue<Node>pq;
pq.push({n,1,dist[n][1]});
//松弛操作
auto relax = [&](int r, int c, int nd)
{
if (r < 1 || r > n) return;
if (c < 1 || c > r) return;
if (nd < dist[r][c]) {
dist[r][c] = nd;
pq.push({r, c, nd});
}
};
while(!pq.empty())
{
Node cur=pq.top();
pq.pop();
int r=cur.r;int c=cur.c;int d=cur.d;
if(d!=dist[r][c])
{
continue;
}
if(r==1&&c==1)
{
break;
}
//左
if(c==1)
{
relax(r,r,d+T[r][r]);
}
else
{
relax(r,c-1,d+T[r][c-1]);
}
//右
if(c<r)
{
relax(r,c+1,d+T[r][c+1]);
}
else relax(r, 1, d + T[r][1]);
//左上
if(r>1)
{
if(c==1)
{
relax(r-1,r-1,d+T[r-1][r-1]);
}
else
{
relax(r-1,c-1,d+T[r-1][c-1]);
}
}
//右上
if(r>1)
{
if(c<r)
{
relax(r-1,c,d+T[r-1][c]);
}
else
{
relax(r-1,1,d+T[r-1][1]);
}
}
}
cout<<dist[1][1]<<"\n";
}