dfs+dp,思路如下 目前的问题是求ans,使用A只能拿95分,使用B就能AC,这是什么原因?
/*
一、DFS选行 i:x~n-r+k 25000次
二、Dp选列 c^3 16*16*16=4096 4e3*2.5e4=1e8
1.状态 dp[y][i] 选y列 以i列结尾的最小分值
2.初始化:0x3f无穷大 dp[1][i]=yy[i]第i列的纵向差
3.状态转移方程:dp[y][i]=min(dp[y][i],dp[y-1][j]+xx[j][i]+yy[i])
y:2~c i:y~m j:y-1~i-1
4.答案 dp[c][i] i:c~m
找到一种行组合的最优解
5.找所有组合的最优解
*/
#include<bits/stdc++.h>
using namespace std;
int n,m,r,c,a[17][17],ans=INT_MAX,ys[17],dp[17][17],xx[17][17],yy[17],b[17][17];
void dfs(int k,int x)//第k个从第x行开始选
{
if(k>r)
{
int i,j,h,y,ans1=INT_MAX;
memset(dp,0x3f,sizeof(dp));
memset(xx,0,sizeof(xx));
memset(yy,0,sizeof(yy));
for(i=1;i<=r;i++)
for(j=1;j<=m;j++) b[i][j]=a[ys[i]][j];
for(i=1;i<m;i++)
for(j=i+1;j<=m;j++)
for(h=1;h<=r;h++) xx[i][j]+=abs(b[h][i]-b[h][j]);
for(j=1;j<=m;j++)
for(h=1;h<r;h++) yy[j]+=abs(b[h][j]-b[h+1][j]);
for(j=1;j<=m;j++) dp[1][j]=yy[j];
for(y=2;y<=c;y++)
for(i=y;i<=m;i++)
{
for(j=y-1;j<=i-1;j++)
dp[y][i]=min(dp[y][i],dp[y-1][j]+xx[j][i]+yy[i]);
//**A**if(y==c) ans1=min(ans1,dp[y][i]);
}
//**B**for(i=c;i<=m;i++) ans1=min(ans1,dp[c][i]);
ans=min(ans,ans1);
return;
}
for(int i=x;i<=n;i++) ys[k]=i,dfs(k+1,i+1);
}
int main()
{
int i,j;
cin>>n>>m>>r>>c;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++) cin>>a[i][j];
dfs(1,1);//枚举行组合 第一个选第一行
cout<<ans;
return 0;
}