• 棋盘分割


    【题目描述】
     将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩 下的矩形棋盘共有n块矩形棋盘。(每次切割都只能沿着棋盘格子的边进行) 

    原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和。现在需要把棋盘按上述规则分割成n块矩形棋盘,并使各矩形棋盘总分的均方差最小。
    请编程对给出的棋盘及n,求出方差的最小值。

    【输入描述】
    第1行为一个整数n(1 < n < 15)。
    第2行至第9行每行为8个小于 100 的非负整数,表示棋盘上相应格子的分值。每行相邻两数之间用一个空格分隔。

    【输出描述】
    仅一个数,为方差(四舍五入精确到小数点后三位)。

    【样例输入】
    3

    1 1 1 1 1 1 1 3

    1 1 1 1 1 1 1 1

    1 1 1 1 1 1 1 1

    1 1 1 1 1 1 1 1

    1 1 1 1 1 1 1 1

    1 1 1 1 1 1 1 1

    1 1 1 1 1 1 1 0

    1 1 1 1 1 1 0 3

    【样例输出】
    1.633

    源代码:
    
    #include<cmath>
    #include<iostream>
    #include<iomanip> //包含【setprecision()】、【fixed】,用于四舍五入保留小数。
    #define INF 1000000000 //定义极大值。
    using namespace std;
    double n,num(0),ans,i[9][9]={0},sum[9][9]={0},f[16][9][9][9][9]; //皆为double类型,方便下面的计算。
    int main()
    {
        cin>>n; //cin输入流。
        int m=n; //作为int类型数组标志变量。
        for (int a=1;a<=8;a++)
          for (int b=1;b<=8;b++)
          {
            cin>>i[a][b];
              num+=i[a][b]; //总和。
              sum[a][b]=sum[a][b-1]+sum[a-1][b]-sum[a-1][b-1]+i[a][b]; //计算[1][1][a][b]的矩形区间和。
          }
        for (int a=1;a<=8;a++)
          for (int b=1;b<=8;b++)
            for (int c=a;c<=8;c++)
              for (int d=b;d<=8;d++)
              {
                  double t;
                t=sum[c][d]-sum[c][b-1]-sum[a-1][d]+sum[a-1][b-1];
                f[0][a][b][c][d]=t*t; //初始化f[切数][x1][y1][x2][y2]数组。
              }
        for (int k=1;k<n;k++) //切了多少次。
          for (int a=1;a<=8;a++)
            for (int b=1;b<=8;b++)
              for (int c=a;c<=8;c++)
                for (int d=b;d<=8;d++)
                {
                    f[k][a][b][c][d]=INF; //初始化。
                    for (int t=a;t<c;t++) //横切。
                    {
                        f[k][a][b][c][d]=min(f[k][a][b][c][d],f[0][a][b][t][d]+f[k-1][t+1][b][c][d]);
                        f[k][a][b][c][d]=min(f[k][a][b][c][d],f[0][t+1][b][c][d]+f[k-1][a][b][t][d]);
                    }
                    for (int t=b;t<d;t++) //纵切。
                    {
                        f[k][a][b][c][d]=min(f[k][a][b][c][d],f[0][a][b][c][t]+f[k-1][a][t+1][c][d]);
                        f[k][a][b][c][d]=min(f[k][a][b][c][d],f[0][a][t+1][c][d]+f[k-1][a][b][c][t]);
                    }
                }
        ans=f[m-1][1][1][8][8]/n-(num/n)*(num/n); //切的次数=矩形个数-1。
        cout<<setprecision(3)<<fixed<<sqrt(ans); //亟待学习。
        return 0;
    }
  • 相关阅读:
    12.2 ROS NavFn全局规划源码解读_2
    12.1 ROS NavFn全局规划源码_1
    12 ROS Movebase主体源码解读
    11 ROS 动态参数调节
    10. ROS costmap代价地图
    无人驾驶汽车1: 基于Frenet优化轨迹的无人车动作规划方法
    VC下加载JPG/GIF/PNG图片的两种方法
    vc++加载透明png图片方法-GDI+和CImage两种
    供CImage类显示的半透明PNG文件处理方法
    使用MFC CImage类绘制PNG图片时遇到的问题
  • 原文地址:https://www.cnblogs.com/Ackermann/p/5352128.html
Copyright © 2020-2023  润新知