zoukankan      html  css  js  c++  java
  • Codeforces 1353F Decreasing Heights(dp)

    题意

    100*100的网格,每个格子有一个初始值,每次操作可以使一个格子的数-1,问你最少多少次操作后存在一条(只往右和下的)(从左上角到右下脚每格递增1的)路径。
    格子权值至多1e15,保证答案存在

    思路

    路径长度显然是固定的,如果路径中有一个基准,那么每个格子应该是多少也是确定的
    而路径中一定是有一个格子不操作的,因为如果所有格子都操作,显然有至少少操作n+m-1次也符合题意的答案
    那么我们可以枚举这个不操作的并且在路径中的格子
    由于它不操作并且在路径中,所以我们可以推出(1,1)的目标值,以及其他所有格子的目标值
    进行dp即可,注意如果当前值比目标值小,这个格子是一定不在路径中的

    代码

    int n,m;
    ll a[101][101];
    ll f[101][101];
    int main() {
        int t;
        scanf("%d", &t);
        mem(f,0x3f);
        while(t--){
            scanf("%d %d", &n, &m);
            for(int i = 1; i <= n; i++){
                for(int j = 1; j <= m; j++){
                    scanf("%lld", &a[i][j]);
                }
            }
            ll ans = INF;
            for(int i = 1; i <= n; i++){
                for(int j = 1; j <= m; j++){
                    ll bs = a[i][j]-i-j+2;
                    for(int l = 1; l <= n; l++){
                        for(int r = 1; r <= m; r++){
                            if(a[l][r]>=bs+l+r-2)f[l][r]=a[l][r]-bs-l-r+2;
                            else f[l][r]=INF;
                        }
                    }
                    for(int l = 1; l <= n; l++){
                        for(int r = 1; r <= m; r++){
                            if(l+r!=2)f[l][r]+=min(f[l-1][r],f[l][r-1]);
                            if(f[l][r]>INF)f[l][r]=INF;
                        }
                    }
                    ans=min(ans,f[n][m]);
                }
            }
            printf("%lld
    ",ans);
    
        }
        return 0;
    }
    
  • 相关阅读:
    CALayer3-层的属性
    CALayer2-创建新的层
    CALayer1-简介
    autofac 使用
    .net5的异步
    动态添加菜单
    PDF解析帮助类
    正则获取字符串中两个字符串间的内容
    水晶报表
    通用easyui查询页面组件
  • 原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/12899711.html
Copyright © 2011-2022 走看看