题意:
思路:先要对公式化简,我的数学好差,花了好长时间化简。然后用记忆化搜索,dp[d][x1][y1][x2][y2] 存储 把大小为(x1,y1)(x2,y2)的矩阵分成d份的最小值。。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> using namespace std; const int INF = 0x7ffffff; int dp[16][9][9][9][9]; int map[9][9]; int n,ans,sum; int dfs(int dep,int x1,int y1,int x2,int y2) { if(dp[dep][x1][y1][x2][y2]>=0) return dp[dep][x1][y1][x2][y2]; int ans=INF; for(int i=x1;i<x2;i++) { int t=dfs(dep-1,i+1,y1,x2,y2)+dp[1][x1][y1][i][y2]; ans = min(t,ans); t = dfs(dep-1,x1,y1,i,y2)+dp[1][i+1][y1][x2][y2]; ans = min(t,ans); } for(int i=y1;i<y2;i++) { int t=dfs(dep-1,x1,i+1,x2,y2)+dp[1][x1][y1][x2][i]; ans = min(t,ans); t = dfs(dep-1,x1,y1,x2,i)+dp[1][x1][i+1][x2][y2]; ans = min(t,ans); } dp[dep][x1][y1][x2][y2] = ans; return ans; } int oor(int x1,int y1,int x2,int y2) { int ans=0; for(int i=x1;i<=x2;i++) for(int j=y1;j<=y2;j++) ans+=map[i][j]; return ans; } void init() { for(int i=0;i<8;i++) for(int k=i;k<8;k++) for(int j=0;j<8;j++) for(int l=j;l<8;l++) { dp[1][i][j][k][l]=oor(i,j,k,l); dp[1][i][j][k][l]=dp[1][i][j][k][l]*dp[1][i][j][k][l]; } } int main() { freopen("in.txt","r",stdin); scanf("%d",&n); memset(dp,-1,sizeof(dp)); for(int i=0;i<8;i++) for(int j=0;j<8;j++) scanf("%d",&map[i][j]),sum+=map[i][j]; init(); ans=dfs(n,0,0,7,7); printf("%.3lf\n",sqrt((ans-1.0*sum/n*sum)/n)); return 0; }