这种题目一般就是d[i][j]当前在第i个点,高度为j,最小代价是多少。但是本题中直接用j的话会非常大,有1e9。但是我们发现在最优的情况下,我们取到的j必然是题目中给出的高度。所以直接把题目中给的距离散化就可以了。这样状态数就是n^2。TC的问题一般n都是50,所以就可以了。
#include <bits/stdc++.h>
#define maxn 109
using namespace std;
const long long INF=1e18;
vector<int>G[maxn],mp,X;
int n,m;
long long d[maxn][maxn],wi[maxn];
bool inq[maxn][maxn];
long long spfa()
{
queue<pair<int,int> >Q;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
d[i][j]=INF;
for(int i=0;i<m;i++)
{
d[0][i]=abs(wi[0]-X[i]);
Q.push(make_pair(0,i));
inq[0][i]=1;
}
long long ans=INF;
while(!Q.empty())
{
pair<int,int> pii=Q.front();
Q.pop();
int u=pii.first,s=pii.second;
inq[u][s]=0;
for(int i=0;i<(int)G[u].size();i++)
{
int v=G[u][i];
for(int j=0;j<=s;j++)
{
if(d[v][j]>d[u][s]+abs(wi[v]-X[j]))
{
d[v][j]=d[u][s]+abs(wi[v]-X[j]);
if(!inq[v][j])
{
inq[v][j]=1;
Q.push(make_pair(v,j));
}
}
}
}
}
for(int j=0;j<m;j++)
ans=min(ans,d[n-1][j]);
return ans;
}
class SkiResorts
{
public: long long minCost(vector <string> road, vector <int> h)
{
n=road.size();
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(road[i][j]=='Y')
G[i].push_back(j);
for(int i=0;i<n;i++)
{
mp.push_back(h[i]);
wi[i]=h[i];
}
sort(mp.begin(),mp.end());
X.push_back(mp[0]);
for(int i=1;i<n;i++)
{
if(mp[i]!=mp[i-1])
X.push_back(mp[i]);
}
m=X.size();
long long ans=spfa();
if(ans>=INF)
ans=-1;
return ans;
}
};