zoukankan      html  css  js  c++  java
  • 【洛谷P2258】子矩阵

    子矩阵

    题目链接

    搜索枚举选了哪几行,将DP降为一个一维的问题,

    先预处理出w[i]表示该列上下元素差的绝对值之和

    v[i][j]为第i列和第j列对应元素之差的绝对值之和

    f[i][j]表示前j列中选i列,且最后一列为j的最小消耗

    f[i][j]=min(f[i][j],f[i-1][j-k]+v[j-k][j]+w[j]);

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    #define reset(a) memset(a,0,sizeof(a))
    #define _reset(a) memset(a,127,sizeof(a))
    #define N 17
    int n,m,r,c,a[N][N],ans=0x3f3f3f3f;
    int f[N][N],w[N],v[N][N],path[N];
    inline int read(){
        int x=0; char c=getchar();
        while(c<'0'||c>'9') c=getchar();
        while('0'<=c&&c<='9') { x=(x<<3)+(x<<1)+c-'0'; c=getchar(); }
        return x;
    }
    void dp(){
        reset(w); reset(v);
        _reset(f);
        for(int i=1;i<=m;i++)
         for(int j=2;j<=r;j++)
          w[i]+=abs(a[path[j]][i]-a[path[j-1]][i]);
        for(int i=1;i<m;i++)
         for(int j=i+1;j<=m;j++)
          for(int k=1;k<=r;k++)
           v[i][j]+=abs(a[path[k]][i]-a[path[k]][j]);
        f[0][0]=0;
        for(int i=1;i<=c;i++)
         for(int j=i;j<=m;j++)
          for(int k=0;k<j;k++)
           f[i][j]=min(f[i][j],f[i-1][k]+w[j]+v[k][j]);
        for(int i=c;i<=m;i++)
         ans=min(ans,f[c][i]);
    }
    void dfs(int t,int minn){
        if(t==r+1){
            dp();
            return;
        }
        for(int i=minn;i<=n;i++){
            path[t]=i;
            dfs(t+1,i+1);
        }
    }
    int main()
    {
        scanf("%d%d%d%d",&n,&m,&r,&c);
        for(int i=1;i<=n;i++)
         for(int j=1;j<=m;j++)
          a[i][j]=read();
        dfs(1,1);
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    [Oracle11g]安装提示不能使用/usr/bin/xdpyinfo命令
    [shell]时间判断
    Share 简易网盘
    VSCODE代码上下对齐插件 — Better Align
    关于 vscode intelephense 错误提示的问题
    2021/11/08 集训补题
    [国家集训队]墨墨的等式
    马大师的分块练习
    20211109 集训补题
    弱智的 线性代数 学习笔记
  • 原文地址:https://www.cnblogs.com/yjkhhh/p/9415937.html
Copyright © 2011-2022 走看看