P2258这道题目相必大家都做过吧。
我这边这种神奇的做法,竟然玄学的对了。
#include<bits/stdc++.h>
#define int long long
#define rnt register int
#define maxn 18
using namespace std;
inline int read()
{
int x=0,f=1;char c;
for(;!isdigit(c);c=getchar()) if(c=='-') f=-f;
for(;isdigit(c);c=getchar()) x=(x<<1)+(x<<3)+(c^48);
return x*f;
}
int n,m,r,c,s[maxn][maxn],col[maxn],d[maxn],f[maxn][maxn],row[maxn][maxn],ans=0x3f3f3f3f;
inline void init()
{
for(rnt j=1;j<=m;j++)
{
col[j]=0;
for(rnt i=2;i<=r;i++)
col[j]+=abs(s[d[i]][j]-s[d[i-1]][j]);
}
for(rnt i=1;i<=m;i++)
for(rnt j=i+1;j<=m;j++)
{
row[i][j]=0;
for(rnt k=1;k<=r;k++)
row[i][j]+=abs(s[d[k]][i]-s[d[k]][j]);
}
}
inline int dp()
{
int ans=0x3f3f3f3f;
for(rnt j=1;j<=m;j++)
{
f[j][0]=0;
for(rnt i=1;i<=min(j,c);i++)
{
f[j][i]=0x3f3f3f3f;
for(rnt k=i-1;k<j;k++)
f[j][i]=min(f[j][i],f[k][i-1]+col[j]+row[k][j]);
}
}
for(rnt j=c;j<=m;j++)
ans=min(ans,f[j][c]);
return ans;
}
inline void dfs(int now,int l) //now代表第now行
{
if(now>r)
{
init();
ans=min(ans,dp());
return;
}
for(d[now]=l+1;d[now]<=n;d[now]++) dfs(now+1,d[now]);
}
signed main()
{
n=read(),m=read(),r=read(),c=read();
for(rnt i=1;i<=n;i++)
for(rnt j=1;j<=m;j++)
s[i][j]=read();
dfs(1,0);
cout << ans << endl;
return 0;
}
AC了。
然而我改了一下maxn,改成20,就挂了