• F. Decreasing Heights(思维+DP)


    题意:一个n*m的矩阵,每一个位置都有一定的高度,要求从(1,1)走到(n,m)并且每次移动只能向下或者向右移动,并且要求只能向比自己高度高1的位置移动。定义一个操作:执行一次可以使得任意一个格子的额高度减一,问从1,1到n,m操作的最少次数。

    题解:首先一定会有一个格子的高度保持不变,设h(i,j)为格子(i,j)的高度。如果说格子在移动的过程中,格子i,j的高度不减少,那么(1,1)的高度一定是h(i,j)-i-j+2。所以可以枚举(1,1)的高度,然后如果(1,1)的高度确定了,那么整个矩阵每个格子的高度也就确定了,然后直接dp就可以了。

    code:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll N=100+7;
    const ll INF=1e18+7; 
    ll arr[N][N];
    vector<ll >ve;
    ll dp[N][N];
    map<ll,bool>mp;
    void solve(){
        ll n,m;
        mp.clear();
        ve.clear();
        cin>>n>>m;
        for(ll i=1;i<=n;i++){
            for(ll j=1;j<=m;j++){
                cin>>arr[i][j];
                ve.push_back(arr[i][j]-i-j+2);
            }
        }
        ll ans=INF;
        for(ll i=0;i<ve.size();i++){ 
            if(mp[ve[i]]) continue ;
            mp[ve[i]]=1;
            if(arr[1][1]<ve[i]) continue ;
            
            for(ll j=0;j<=n;j++){
                for(ll k=0;k<=m;k++){
                    dp[j][k]=INF;
                }
            }
            dp[1][1]=arr[1][1]-ve[i]; 
            for(ll j=1;j<=n;j++){
                for(ll k=1;k<=m;k++){ 
                    if(arr[j][k]-j-k+2>=ve[i]){
                        dp[j][k]=min(dp[j][k],min(dp[j][k-1],dp[j-1][k])+arr[j][k]-j-k+2-ve[i]);
                    }
                }
            } 
            ans=min(ans,dp[n][m]);
        }
        cout<<ans<<endl;
    }
    int main(){
        ll t;
        cin>>t;
        while(t--) solve();
        return 0;
    }
  • 相关阅读:
    思考-少写代码
    app上传 那些事儿!
    vs2010 找不到本地服务器
    如何成为一名优秀得程序员
    python成功之路,Day2-判断和循环语句
    python成功之路,Day1-发展历史
    ES6学习笔记2-字符串扩展
    ES6学习笔记1-解构赋值
    数组的方法
    ES6
  • 原文地址:https://www.cnblogs.com/Accepting/p/12939562.html
Copyright © 2020-2023  润新知