做法:
设立数组f[x1][y1][x2][y2][k]表示在矩形x1y1,x2y2中还需切割k-1次;
逐步递推即可。
#include<stdio.h> #include<math.h> #include<iostream> #include<string.h> #include<algorithm> #include<queue> #include<stack> #include<map> #include<string> #include<stdlib.h> #define INF_MAX 0x7fffffff #define INF 999999 #define max3(a,b,c) (max(a,b)>c?max(a,b):c) #define min3(a,b,c) (min(a,b)<c?min(a,b):c) #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; struct node { int u; int v; int w; bool friend operator < (node a, node b){ return a.w < b.w; } }edge[1001]; int gcd(int n,int m){if(n<m) swap(n,m);return n%m==0?m:gcd(m,n%m);} int lcm(int n,int m){if(n<m) swap(n,m);return n/gcd(n,m)*m;} int f[10][10][10][10][21]; int p[10][10][10][10]; int a[10][10]; int init(int x1,int y1,int x2,int y2) { if(p[x1][y1][x2][y2]>=0)return p[x1][y1][x2][y2]; int sum; sum=0; int i,j; for(i=x1;i<=x2;i++) { for(j=y1;j<=y2;j++) { sum+=a[i][j]; } } p[x1][y1][x2][y2]=sum*sum; // printf("-----%d %d %d %d %d\n",x1,y1,x2,y2,sum*sum); return sum*sum; } int dos(int x1,int y1,int x2,int y2,int k) { int i; if(k==1)return init(x1,y1,x2,y2); if(f[x1][y1][x2][y2][k]>=0)return f[x1][y1][x2][y2][k]; int mins=99999999; for(i=x1;i<x2;i++) { mins=min3(mins,(dos(i+1,y1,x2,y2,k-1)+init(x1,y1,i,y2)),(init(i+1,y1,x2,y2)+dos(x1,y1,i,y2,k-1))); } for(i=y1;i<y2;i++) { mins=min3(mins,(dos(x1,i+1,x2,y2,k-1)+init(x1,y1,x2,i)),(init(x1,i+1,x2,y2)+dos(x1,y1,x2,i,k-1))); } f[x1][y1][x2][y2][k]=mins; //printf("%d %d %d %d %d %d\n",x1,y1,x2,y2,k,mins); return mins; } int main() { int n,i,j,ans; scanf("%d",&n); double x; x=0; mem(f,-1); mem(p,-1); for(i=1;i<=8;i++) { for(j=1;j<=8;j++) scanf("%d",&a[i][j]); } x=1.0*x/n; x=x*x; ans=dos(1,1,8,8,n); x=(sqrt(1.0*init(1,1,8,8))/n); printf("%.3f\n",sqrt(1.0*ans/n-x*x)); return 0; }