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; }