zoukankan      html  css  js  c++  java
  • poj 1191 棋盘分割(dp + 记忆化搜索)

    题目:http://poj.org/problem?id=1191

    黑书116页的例题

    将方差公式化简之后就是 每一块和的平方 相加/n , 减去平均值的平方。

    可以看出来 方差只与 每一块的和的平方有关,所以就是求每个矩形的总分的平方和 尽量小。。。。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <algorithm>
     7 using namespace std;
     8 const int INF = 1<<28;
     9 int sum[10][10], d[20][10][10][10][10];//sum存储从【1,1】到【i, j】的和
    10 int _min(int a, int b)
    11 {
    12     return a>b?b:a;
    13 }
    14 int getsum(int x1, int y1, int x2, int y2) //计算从【x1,y1】到【x2, y2】的和。
    15 {
    16     return sum[x2][y2]-sum[x1-1][y2]-sum[x2][y1-1]+sum[x1-1][y1-1];
    17 }
    18 int slove(int k, int x1, int y1, int x2, int y2)
    19 {
    20     int s1, s2, Min, temp1, temp2;
    21     int i;
    22     if(d[k][x1][y1][x2][y2]!=-1) //不等于1表示已经求过了,不需要再求了
    23     return d[k][x1][y1][x2][y2];
    24     if(k == 1)  //表示已经切了n块了,不需要再切了
    25     {
    26         s1 = getsum(x1, y1, x2, y2);
    27         return (d[k][x1][y1][x2][y2] = s1*s1);
    28     }
    29     Min = INF;
    30     for(i = x1; i < x2; i++)  //横向切
    31     {
    32         s1 = getsum(x1, y1, i, y2);
    33         s2 = getsum(i+1, y1, x2, y2);
    34         temp1 = _min(slove(k-1, i+1, y1, x2, y2)+s1*s1, slove(k-1, x1, y1, i, y2)+s2*s2);
    35         if(temp1 < Min)
    36         Min = temp1;
    37     }
    38     for(i = y1; i < y2; i++) //纵向切
    39     {
    40         s1 = getsum(x1, y1, x2, i);
    41         s2 = getsum(x1, i+1, x2, y2);
    42         temp2 = _min(slove(k-1, x1, i+1, x2, y2)+s1*s1, slove(k-1, x1, y1, x2, i)+s2*s2);
    43         if(temp2 < Min)
    44         Min = temp2;
    45     }
    46     return (d[k][x1][y1][x2][y2] = Min);
    47 }
    48 int main()
    49 {
    50     int n, i, j, val, x;
    51     double aver, var;
    52     while(~scanf("%d", &n))
    53     {
    54         memset(d, -1, sizeof(d));
    55         memset(sum, 0, sizeof(sum));
    56         for(i = 1; i <= 8; i++)
    57         for(j = 1, x = 0; j <= 8; j++)
    58         {
    59             scanf("%d", &val);
    60             x += val;
    61             sum[i][j] = sum[i-1][j] + x;
    62         }
    63         aver = sum[8][8]*1.0/n;  //所有块的平方和
    64         int sum_t = slove(n, 1, 1, 8, 8);
    65         var = sqrt(sum_t*1.0/n-aver*aver);
    66 
    67         printf("%.3lf
    ", var);
    68     }
    69     return 0;
    70 }
  • 相关阅读:
    Pipe
    An Easy Problem?!
    Kadj Squares
    Space Ant
    Intersection
    让网页变为可编辑状态
    typescript入门基础
    大家都能看懂的 canvas基础教程
    数组的foreach方法和jQuery中的each方法
    html单行、多行文本溢出隐藏
  • 原文地址:https://www.cnblogs.com/bfshm/p/3567737.html
Copyright © 2011-2022 走看看