luogu_2258 子矩阵

#include <cstdio>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int INF=1<<30;
int n,m,c,r,a[20][20],q[20],cnt=1,f[20][20],lc[20],hc[20][20],minn=INF;
 
inline int read(){
    char cc; int x=0;
    cc=getchar();
    while(!isdigit(cc))cc=getchar();
    while(isdigit(cc)){
        x=x*10+cc-'0';
        cc=getchar();
    }
    return x;
}

inline void init(){
    for(register int i=1;i<=m;i++){
        lc[i]=0;
        for(register int j=1;j<r;j++)lc[i]+=abs(a[q[j]][i]-a[q[j+1]][i]);
    }
    for(register int i=2;i<=m;i++)
        for(register int j=1;j<i;j++){
            hc[i][j]=0;
            for(register int k=1;k<=r;k++)hc[i][j]+=abs(a[q[k]][i]-a[q[k]][j]);
        }
}
 
inline void dp(){
    for(register int i=1;i<=m;i++){
        int cmin=min(i,c);
        for(register int j=1;j<=cmin;j++){
            if(j==1)f[i][j]=lc[i]; 
            else if(i==j)f[i][j]=f[i-1][j-1]+lc[i]+hc[i][j-1];
            else{
                f[i][j]=INF;
                for(register int k=j-1;k<i;k++)f[i][j]=min(f[i][j],f[k][j-1]+lc[i]+hc[i][k]);
            }
            if(j==c)minn=min(minn,f[i][c]);
        }
    }
}
 
 
inline void dfs(int now){
    if(now>n){init(); dp(); return;}
    if(r-cnt==n-now){
        q[cnt++]=now;
        dfs(now+1);
        q[cnt--]=0;
        return;
    }
    dfs(now+1);
    if(cnt<=r){
        q[cnt++]=now;
        dfs(now+1);
        q[cnt--]=0;
    }
}
 
int main(){
    n=read(); m=read(); r=read(); c=read();
    for(register int i=1;i<=n;i++)
        for(register int j=1;j<=m;j++)a[i][j]=read();
    dfs(1);
    printf("%d\n",minn);
    return 0;
}

  

posted @ 2017-10-11 17:13  wqtnb_tql_qwq_%%%  阅读(302)  评论(0编辑  收藏  举报