• poj1191 棋盘分割【区间DP】【记忆化搜索】


    棋盘分割
    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions: 16263   Accepted: 5812

    Description

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

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

    Input

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

    Output

    仅一个数,为O'(四舍五入精确到小数点后三位)。

    Sample Input

    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

    Sample Output

    1.633

    Source

    题意:

    一个8*8的棋盘,进行分割。每次将一个矩形分割成两个。一个矩形的值是里面所有格子值之和。现在想切出n个矩形,希望求得最小的均方差。

    思路:

    我们先把均方差的公式进行化简

    平均值是一个定值,因为每个矩形都是格子值之和。于是我们发现结果之和Xi平方有关。Xi平方越小越好。

    对于每一个格子,都可以用两个坐标(i, j)和(x,y)表示,他们分别是矩形的左上角和右下角。

    一个矩形有两种切割方法,横着切,竖着切,假设在k处切

    横着切时,矩形被分成了(i, j)(k, y) 和 (k + 1, j)(x,y)

    竖着切时,矩形被分成了(i,j)(x,k) 和(i, k+1)(x,y)

    但是这样还没办法进行状态转移,因为矩形的先后顺序不知道。所以我们可以再引入一维变量,表示各自的顺序。

    于是在切割i次时,得到两个矩形,其中一个应该是i+1次切割的矩形。可以得到状态转移方程。

     因为是i推i+1,所以用记忆化搜索写起来可能方便一点

     1 //#include <bits/stdc++.h>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<stdio.h>
     6 #include<cstring>
     7 #include<vector>
     8 #include<map>
     9 #include<set>
    10 
    11 #define inf 0x3f3f3f3f
    12 using namespace std;
    13 typedef long long LL;
    14 
    15 int n;
    16 int board[10][10], hang[10][10], dp[20][10][10][10][10];
    17 
    18 /*int getval(int i, int j, int x, int y)
    19 {
    20     int res = 0;
    21     for(int k = i; k <= x; k++){
    22         res += hang[i][y] - hang[i][j - 1];
    23     }
    24     return res * res;
    25 }*/
    26 
    27 int getval(int i, int j, int x, int y)
    28 {
    29     int res = 0;
    30     for(int a = i; a <= x; a++){
    31         for(int b = j; b <= y; b++){
    32             res += board[a][b];
    33         }
    34     }
    35     return res * res;
    36 }
    37 
    38 int DP(int k, int i, int j, int x, int y)
    39 {
    40     int ans = 0;
    41     if(dp[k][i][j][x][y] >= 0)return dp[k][i][j][x][y];
    42     if(k == n - 1){
    43         return getval(i, j, x, y);
    44     }
    45     dp[k][i][j][x][y] = inf;
    46     for(int tmp = i; tmp < x; tmp++){
    47         ans = min(DP(k + 1, i, j, tmp, y) + getval(tmp + 1, j, x, y), DP(k + 1, tmp + 1, j, x, y) + getval(i, j, tmp, y));
    48         dp[k][i][j][x][y] = min(ans, dp[k][i][j][x][y]);
    49     }
    50     for(int tmp = j; tmp < y; tmp++){
    51         ans = min(DP(k + 1, i, j, x, tmp) + getval(i, tmp + 1, x, y), DP(k + 1, i, tmp + 1, x, y) + getval(i, j, x, tmp));
    52         dp[k][i][j][x][y] = min(ans, dp[k][i][j][x][y]);
    53     }
    54     return dp[k][i][j][x][y];
    55 }
    56 
    57 int main(){
    58 
    59     while(scanf("%d", &n) != EOF){
    60         double sum = 0;
    61         memset(hang, 0, sizeof(hang));
    62         for(int i = 1; i <= 8; i++){
    63             for(int j = 1; j <= 8; j++){
    64                 scanf("%d", &board[i][j]);
    65                 sum += board[i][j] * 1.0;
    66                 hang[i][j] = hang[i][j - 1] + board[i][j];
    67             }
    68         }
    69         sum /= 1.0 * n;
    70         memset(dp, -1, sizeof(dp));
    71         int ans = DP(0, 1, 1, 8, 8);
    72         //cout<<ans<<endl;
    73         //cout<<dp[n - 1][1][1][8][8]<<endl;
    74         printf("%.3f
    ",sqrt((dp[0][1][1][8][8])*1.0/n-sum*sum));
    75     }
    76     return 0;
    77 }
  • 相关阅读:
    如何保证最少消费一次redis的list队列数据
    如果设置Redis客户端的超时时长?
    REdis一致性方案探讨
    Linux后台开发工具箱-葵花宝典
    REdis主从复制之repl_backlog
    C++之Lambda研究
    Redis-5.0.5集群配置
    REdis之maxmemory解读
    [转载]centos6.3安装启动使用PostgreSQL 9.2
    [转载]linux环境变量设置方法总结(PATH/LD_LIBRARY_PATH)
  • 原文地址:https://www.cnblogs.com/wyboooo/p/9780408.html
Copyright © 2020-2023  润新知