• 棋盘分割


    棋盘分割

    对一个(8 imes 8)的矩形网格图进行划分,第i行第j列里的数字为(a[i][j]),当然,接下来的操作都是在网格线上操作的,每次操作可以将矩形网格图划分成两个矩形网格图,对任意其中一个继续同样操作,给出一个数字n,显然,进行n-1次操作后会有n个矩形网格图,定义一个矩形网格图的分数为里面所有的数字之和,求分数的方差的最小值,(nleq 15)

    显然,问题具有可划分性,但是不知道方差是否具有最优子结构性质,于是先对式子进行研究,设(x_i)为第i个矩形网格图的分数,(ar{x})为矩形网格图的平均数,不难有(ar{x}=frac{sum_{i=1}^nx_i}{n}),显然,它是一个定值,而方差为

    [sqrt{frac{sum_{i=1}^n(x_i-ar{x})^2}{n}} ]

    于是实际上递推的为(sum_{i=1}^n(x_i-ar{x})^2)的最小值,这个是具有最优子结构性质的,设(val(y_1,x_1,y_2,x_2))为以((y_1,x_1))为左上角,((y_2,x_2))为右下角的矩形的分数,这个不难(O(n^2))维护,(O(1))查询,设(dp[n][y_1][x_1][y_2][x_2])为以((y_1,x_1))为左上角,((y_2,x_2))为右下角的矩形划分n次的(sum_{i=1}^n(x_i-ar{x})^2)的最小值,于是不难有
    (设(ar{x})为预先处理出的平均数,(&x=f[n][y_1][x_1][y_2][x_2]))

    [x=min(x,min_{p=y_1}^{y_2-1}{f[n-1][y_1][x_1][p][x_2]+(val(p-1,x_1,y_2,x_2)-ar{x})^2}) ]

    [x=min(x,min_{p=y_1}^{y_2-1}{f[n-1][p-1][x_1][y_2][x_2]+(val(y_1,x_1,p,x_2)-ar{x})^2}) ]

    [x=min(x,min_{p=x_1}^{x_2-1}{f[n-1][p][x_2][y_1][x_1]+(val(y_1,p-1,y_2,x_2)-ar{x})^2}) ]

    [x=min(x,min_{p=x_1}^{x_2-1}{f[n-1][y_1][p-1][y_2][x_2]+(val(p,x_2,y_1,x_1)-ar{x})^2}) ]

    边界:(f[0][i][j][k][l]=val(i,j,k,l))

    答案:(sqrt{frac{f[n-1][1][1][8][8]}{n}})

    参考代码:

    不具有明显阶段性,故用dfs实现

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #define il inline
    #define ri register
    using namespace std;
    int a[9][9];
    bool is[16][9][9][9][9];
    double dp[16][9][9][9][9],x_,
        dfs(int,int,int,int,int);
    il int val(int,int,int,int);
    il double min(double,double),pow2(double);
    int main(){
        int n;scanf("%d",&n);
        for(int i(1),j;i<9;++i)
            for(j=1;j<9;++j)
                scanf("%d",&a[i][j]),x_+=a[i][j],
                    a[i][j]+=a[i][j-1]+a[i-1][j]-a[i-1][j-1];
        x_/=n,memset(dp,66,sizeof(dp));
        for(int i(1),j,k,l;i<9;++i)
            for(j=1;j<9;++j)
                for(k=i;k<9;++k)
                    for(l=j;l<9;++l)
                        dp[0][i][j][k][l]=pow2(val(i,j,k,l)-x_),
                            is[0][i][j][k][l]|=true;
        printf("%.3f",sqrt(dfs(n-1,1,1,8,8)/n));
        return 0;
    }
    il double pow2(double x){
        return x*x;
    }
    il double min(double a,double b){
        return a<b?a:b;
    }
    double dfs(int n,int y1,int x1,int y2,int x2){
        double &x(dp[n][y1][x1][y2][x2]);
        if(is[n][y1][x1][y2][x2])return x;
        int lsy(1);
        for(int p(y1);p<y2;++p)
            x=min(x,dfs(n-1,y1,x1,p,x2)+pow2(val(p+1,x1,y2,x2)-x_)),
                x=min(x,dfs(n-1,p+1,x1,y2,x2)+pow2(val(y1,x1,p,x2)-x_));
        for(int p(x1);p<x2;++p)
            x=min(x,dfs(n-1,y1,x1,y2,p)+pow2(val(y1,p+1,y2,x2)-x_)),
                x=min(x,dfs(n-1,y1,p+1,y2,x2)+pow2(val(y1,x1,y2,p)-x_));
        return is[n][y1][x1][y2][x2]|=true,x;
    }
    il int val(int y1,int x1,int y2,int x2){
        return a[y2][x2]+a[y1-1][x1-1]-a[y2][x1-1]-a[y1-1][x2];
    }
    
  • 相关阅读:
    iphone在iframe页面的宽度不受父页面影响,避免撑开页面
    touch事件应用
    js获取手机屏幕宽度、高度
    css3特效样式库
    js基础:对DOM进行操作,删除、添加元素
    eval基础,基础用法及解析json
    ajax调用数据案例,二级联动
    (原)String类两种实例化的区别
    java订电影票系统
    多线程练习(java)
  • 原文地址:https://www.cnblogs.com/a1b3c7d9/p/11001561.html
Copyright © 2020-2023  润新知