Luogu P1436 棋盘分割 暴力DP
我的天,,,,,n=8,k<=15,,,这怕不是暴力DP+高维数组。。。。
开一个五维数组f[k][i][j][p][q]表示从(i,j)到(p,q)中分成k个矩形最小的平方和。
然后初始化时用上二维前缀和
DP时有些像区间DP,枚举分割线,分成两部分,取min就好
#include<cstdio> #include<iostream> #include<cstring> #define R register int #define For(i,a,b) for(R i=a;i<=b;++i) #define ffor(i,a,b) for(R i=b;i>=a;--i) const int N=8; using namespace std; inline int g() { R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix; } inline void ckmn(int& a,int b) {b<a?a=b:a=a;} int n; int f[N<<1][N][N][N][N],a[N][N],s[N][N]; signed main() { memset(f,0x3f,sizeof(f)); n=g(); For(i,1,8) For(j,1,8) a[i][j]=g(); For(i,1,8) For(j,1,8) s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j]; For(i,1,8) For(j,1,8) For(p,i,8) For(q,j,8) { R tmp=s[p][q]-s[p][j-1]-s[i-1][q]+s[i-1][j-1]; f[1][i][j][p][q]=tmp*tmp; } For(tk,2,n) ffor(i,1,8) ffor(j,1,8) For(p,i,8) For(q,i,8) { For(t,i+1,p) ckmn(f[tk][i][j][p][q],min(f[tk-1][i][j][t-1][q]+f[1][t][j][p][q],f[1][i][j][t-1][q]+f[tk-1][t][j][p][q])); For(t,j+1,q) ckmn(f[tk][i][j][p][q],min(f[tk-1][i][j][p][t-1]+f[1][i][t][p][q],f[1][i][j][p][t-1]+f[tk-1][i][t][p][q])); } printf("%d\n",f[n][1][1][8][8]); }
第一次define for循环,太多了。。QAQ。。。
2019.04.28