题面:https://www.luogu.org/problem/P1436
设f[k][i][j][x][y]为切了k次从(i,j)到(x,y)矩形的最大解。
那么DP方程就很好写出来了。
f[k][i][j][x][y]=min(f[k][i][j][x][y],min(f[1][i][j][a][y]+f[k-1][a+1][j][x][y],f[k-1][i][j][a][y]+f[1][a+1][j][x][y])); f[k][i][j][x][y]=min(f[k][i][j][x][y],min(f[1][i][j][x][a]+f[k-1][i][a+1][x][y],f[k-1][i][j][x][a]+f[1][i][a+1][x][y]));
虽然有一点点长,但是还是很好理解。
就是把当前的分为两半。
一半切k-1刀,另外一半是这1刀。
这样就合并成了。
全部代码如下:
#include<bits/stdc++.h> #define ll long long using namespace std; int n,tu[10][10]; ll sum[10][10]; ll f[20][10][10][10][10]; int main() { scanf("%d",&n); for(int i=1;i<=8;i++) for(int j=1;j<=8;j++) scanf("%d",&tu[i][j]); for(int i=1;i<=8;i++) for(int j=1;j<=8;j++) sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+tu[i][j]; memset(f,0x3f,sizeof(f)); for(int i=1;i<=8;i++) for(int j=1;j<=8;j++) for(int x=1;x<=8;x++) for(int y=1;y<=8;y++){ ll now=sum[x][y]-sum[i-1][y]-sum[x][j-1]+sum[i-1][j-1]; f[1][i][j][x][y]=now*now; } for(int k=2;k<=n;k++) for(int i=1;i<=8;i++) for(int j=1;j<=8;j++) for(int x=i;x<=8;x++) for(int y=i;y<=8;y++){ for(int a=i;a<x;a++) f[k][i][j][x][y]=min(f[k][i][j][x][y],min(f[1][i][j][a][y]+f[k-1][a+1][j][x][y],f[k-1][i][j][a][y]+f[1][a+1][j][x][y])); for(int a=j;a<y;a++) f[k][i][j][x][y]=min(f[k][i][j][x][y],min(f[1][i][j][x][a]+f[k-1][i][a+1][x][y],f[k-1][i][j][x][a]+f[1][i][a+1][x][y])); } printf("%lld\n",f[n][1][1][8][8]); return 0; }