Decreasing Heights - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
看到数据范围,就应该往O(n^3) 或 O(n^4)的时间复杂度靠
假设有一条合法路径,现在到了 (i,j) 处的高度,那么此处高度与(1,1)的高度相对差距便是 i+j-2.
我们对每一处的高度都减去(i+j-2),再去找合法路径,那么题意就转化成转化成同一高度所需的最小代价。(本题的思维难点)
我们观察题目数据范围,发现 N<=100
所以我们暴力枚举每一处的高度以作为合法路径的高度。
假设现在我们选择了 x 作为合法路径高度,那么如何算这个最小代价呢?
显然只有dp可以算,令dp[i][j]:到 (i,j) 时,所需的最小代价,最终代价便是dp[n][m]。
枚举每一处高度为O(n^2),每一处高度进行dp为O(n^2).总时间复杂度便是O(n^4).
Code:
#include<bits/stdc++.h> using namespace std; #define ll long long #define mp make_pair #define pb push_back #define popb pop_back #define fi first #define se second #define popcount __builtin_popcount #define popcountll __builtin_popcountll const int N=150; //const int M=; //const int inf=(int)1e9; const ll INF=(ll)1e18; int T,n,m; ll a[N][N],dp[N][N]; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; } ll solvedp(ll x) { for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) dp[i][j]=INF; if(a[1][1]<x) return INF; dp[1][1]=a[1][1]-x; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(i==1&&j==1 || a[i][j]<x) continue; if(i==1) dp[i][j]=dp[i][j-1]+a[i][j]-x; else if(j==1) dp[i][j]=dp[i-1][j]+a[i][j]-x; else dp[i][j]=min(dp[i-1][j],dp[i][j-1])+a[i][j]-x; } return dp[n][m]; } int main() { // freopen("","r",stdin); // freopen("","w",stdout); // ios::sync_with_stdio(0); // cin.tie(0); T=read(); while(T--) { n=read(),m=read(); 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); // for(int i=1;i<=n;i++,puts("")) // for(int j=1;j<=m;j++) // printf("%lld ",a[i][j]); ll ans=INF; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) ans=min(ans,solvedp(a[i][j])); printf("%lld\n",ans); } return 0; }
标签:ch,const,int,高度,CF1353F,dp,define From: https://www.cnblogs.com/Willette/p/17426539.html