棋盘分割







import java.util.Scanner;

public class Main {
    
    static int[][]s;        //每个格子的分数
    static int[][]sum;      //从(1,1)到(i,j)的矩形的分数之和
    static int[][][][][]res;  //fun的记录表
    
    public static int calSum(int x1,int y1,int x2,int y2) {//从(x1,y1)到(x2,y2)的矩形的分数之和
        
        return sum[x2][y2] - sum[x2][y1-1]-sum[x1-1][y2]+sum[x1-1][y1-1];
    }
    
    public static int fun(int n,int x1,int y1,int x2,int y2) {
        
        int t,a,b,c,e,MIN=Integer.MAX_VALUE;
        if(res[n][x1][y1][x2][y2]!=-1)
            return res[n][x1][y1][x2][y2];
        if(n==1) {
            t = calSum(x1, y1, x2, y2);
            res[n][x1][y1][x2][y2] = t*t;
            return t*t;
        }
        for(a=x1;a<x2;a++) {
            /*          x = a
             *    -------|----------
             *    -         |             -
             *    -   e    |  c         -
             *    -------|----------
             */
            c = calSum(a+1, y1, x2, y2);
            e = calSum(x1, y1, a, y2);
            t = Math.min(fun(n-1, x1, y1, a, y2) + c*c, fun(n-1, a+1, y1, x2, y2)+e*e);
            if(t<MIN)MIN = t;
        }
        
        for(b=y1;b<y2;b++) {
            
            /*    -----------------
             *    -        e            -
             *  — —  — — — — — y=b
             *    -        c            -
             *    -----------------
             */
            c = calSum(x1, b+1, x2, y2);
            e = calSum(x1, y1, x2, b);
            t = Math.min(fun(n-1, x1, y1, x2, b) + c*c, fun(n-1, x1, b+1, x2, y2)+e*e);
            if(t<MIN)MIN = t;
        }
        res[n][x1][y1][x2][y2] = MIN;
        return MIN;
    }
    
    public static void main(String[] args) {
        
        s = new int[9][9];
        sum = new int[9][9];
        res = new int[15][9][9][9][9];
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        for(int i=1;i<9;i++) {
            for(int j=1,rowsum=0;j<9;j++) {
                s[i][j] = in.nextInt();
                rowsum+=s[i][j];
                sum[i][j] += sum[i-1][j] + rowsum;  //前一行的分数之和加上当前行的分数之和
            }
        }
    
        InitRes(res);
        System.out.printf("%.3f",Math.sqrt((double)fun(n, 1, 1, 8, 8)/n-(double)(sum[8][8]*sum[8][8])/(n*n)));
        in.close();
    }
    //初始化res全为-1
    public static void InitRes(int[][][][][]res) {
        int i,j,k,l,m;
        for(i=0;i<15;i++)
            for(j=0;j<9;j++)
                for(k=0;k<9;k++)
                    for(l=0;l<9;l++)
                        for(m=0;m<9;m++)
                            res[i][j][k][l][m] = -1;
    
    }
}


猜你喜欢

转载自blog.csdn.net/l903445981/article/details/79943099