It should be easy to think of violence cheat points.
We consider violence \ (dfs \) to enumerate all selected rows, columns selection, every note of the score can be run again.
Time complexity: \ (O (R & lt C_n ^ \ ^ Times C_m C \ R & lt Times \ Times C) \)
Water can be too \ (60pts \) .
#include<bits/stdc++.h>
#define INF 1000000007
using namespace std;
inline int read(){
register int s=0,f=1;
register char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f*=-1;ch=getchar();}
while(isdigit(ch))s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
return s*f;
}
const int N=20;
int n,m,r,c,ans=INF;
int a[N][N],fh[N],fl[N];
int solve(){
int sum=0;
for(int i=1;i<=r;i++){
for(int j=1;j<c;j++){
sum+=abs(a[fh[i]][fl[j]]-a[fh[i]][fl[j+1]]);
}
}
for(int j=1;j<=c;j++){
for(int i=1;i<r;i++){
sum+=abs(a[fh[i]][fl[j]]-a[fh[i+1]][fl[j]]);
}
}
return sum;
}
void dfsl(int dep,int cnt){
if(cnt>c){ans=min(ans,solve());return;}
if(dep>m)return;
fl[cnt]=dep;dfsl(dep+1,cnt+1);
fl[cnt]=0;dfsl(dep+1,cnt);
}
void dfsh(int dep,int cnt){
if(cnt>r){dfsl(1,1);return;}
if(dep>n)return;
fh[cnt]=dep;dfsh(dep+1,cnt+1);
fh[cnt]=0;dfsh(dep+1,cnt);
}
int main(){
ios::sync_with_stdio(false);
n=read(),m=read(),r=read(),c=read();
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
a[i][j]=read();
}
}
dfsh(1,1);
cout<<ans<<endl;
return 0;
}
【Analysis of Algorithms】
We are still the first choice to hold the pieces, so the next question translates into:
- A \ (r \ times m \) matrix selected from the group \ (C \) column, so that the minimum value.
Obviously, this is a \ (01 \) the selection of the column, so we direct \ (dp \) just fine.
Reset state \ (dp [i] [j ] \) is the current choice of \ (I \) while the column has been selected \ (J \) minimum score column.
Next we pretreatment two good things:
\ (up [i] \) represents the current row selection Dir \ (I \) total score column.
\ ([i] num [j ] \) indicates the connection of the current row selection \ (I \) column and \ (J \) score column.
So for the first \ (dp [i] [J] \) , we just need to re-enumerate a first \ (k \) columns. When the connection section \ (K \) column and \ (I \) when the column itself is the value of \ (I \) column value \ (up [i] \) and the connection of the two scores \ ( NUM [I] [K] \) .
So difficult to launch:
\[dp[i][j]=min\{ dp[k][j-1]+up[i]+num[k][i] \} \]
\[i \in [1,m],j\in[2,min(i,c)],k \in[1,i)\]
Boundary treatment:
\[dp=\{0x7f\},dp[i][1]=up[i]\]
Update minimum score:
\[ans=min\{dp[i][c]\}\]
Time complexity: \ (O (R & lt C_n ^ \ ^ 2N Times m) \)
#include<bits/stdc++.h>
#define INF 1000000007
using namespace std;
inline int read(){
register int s=0,f=1;
register char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f*=-1;ch=getchar();}
while(isdigit(ch))s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
return s*f;
}
const int N=20;
int n,m,r,c,ans=INF;
int a[N][N],f[N],up[N],num[N][N],dp[N][N];
void solve(){
memset(up,0,sizeof(up));
memset(num,0,sizeof(num));
for(int j=1;j<=m;j++){
for(int i=1;i<r;i++){
up[j]+=abs(a[f[i]][j]-a[f[i+1]][j]);
}
}
for(int i=1;i<=m;i++){
for(int j=i+1;j<=m;j++){
for(int k=1;k<=r;k++){
num[i][j]+=abs(a[f[k]][i]-a[f[k]][j]);
}
}
}
memset(dp,0x7f,sizeof(dp));
int tot=INF;
for(int i=1;i<=m;i++){
dp[i][1]=up[i];
for(int j=2;j<=min(i,c);j++){
for(int k=1;k<i;k++){
dp[i][j]=min(dp[i][j],dp[k][j-1]+up[i]+num[k][i]);
}
}
tot=min(tot,dp[i][c]);
}
ans=min(ans,tot);
}
void dfs(int dep,int cnt){
if(cnt>r){solve();return;}
if(dep>n)return;
f[cnt]=dep;dfs(dep+1,cnt+1);
f[cnt]=0;dfs(dep+1,cnt);
}
int main(){
ios::sync_with_stdio(false);
n=read(),m=read(),r=read(),c=read();
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
a[i][j]=read();
}
}
dfs(1,1);
cout<<ans<<endl;
return 0;
}