F. Decreasing Heights(思维,dp)
题:https://codeforces.com/contest/1353/problem/F
题意:给定n*m的矩形,每个位置都有aij的高度,位于某一位置你只能向下或向右走,且得满足下一个格子高度y和当前格子高度x条件:y==x+1;
分析:我们可以把题目条件转化为y==x,那么就可以通过确定一个高度dp地从[1,1]往下找一个权值和最小路径。这个转化,就对于每一个位置减去(i+j-2)即可;
dp过程:假设经过某条路径,那么这条路径上的某一高度权值一定不变,
#include<cstdio> #include<iostream> #include<vector> #include<algorithm> #include<unordered_map> using namespace std; #define pb push_back typedef long long ll; const int M=1e2+2; const ll INF=1e18; unordered_map<ll,int>mp; ll dp[M][M],a[M][M]; int main(){ int t; scanf("%d",&t); while(t--){ int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ scanf("%lld",&a[i][j]); a[i][j]-=(i+j-2);///让题目条件转化为走的路径要高度相同 } mp.clear(); ll ans=INF; for(int x=1;x<=n;x++) for(int y=1;y<=m;y++){ if(mp[a[x][y]]) continue; mp[a[x][y]]=1; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) dp[i][j]=INF; if(a[1][1]-a[x][y]<0) continue; dp[1][1]=a[1][1]-a[x][y]; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ if(a[i+1][j]>=a[x][y]) dp[i+1][j]=min(dp[i+1][j],dp[i][j]+(a[i+1][j]-a[x][y])); if(a[i][j+1]>=a[x][y]) dp[i][j+1]=min(dp[i][j+1],dp[i][j]+(a[i][j+1]-a[x][y])); } ans=min(ans,dp[n][m]); } printf("%lld\n",ans); } return 0; }