poj1191--棋盘分割(dp)

棋盘分割

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 12671   Accepted: 4497

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

求方差最小

(x1,y1)代表一个方块的左上角,(x2,y2)方块的右下角。

dp[i][j] i表示当前分割为i块是,并且,最后一块为j,j = x1 * 1000 + y1 * 100 + x2 * 10 + y2,将一个方块的坐标压到一个数中,让dp[i][j]最小,最终得到dp[n][j]找出最小值

对于每一个方块枚举可以切开的位置,和之后得到的方块,。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std ;
#define LL __int64
#define INF 0x3f3f3f3f
int Map[10][10] ;
double dp[20][11000] ;
double f(int x1,int y1,int x2,int y2,double x)
{
    double ans ;
    ans = Map[x2][y2] - Map[x2][y1] - Map[x1][y2] + Map[x1][y1] ;
    ans = ( ans - x ) * ( ans - x ) ;
    return ans ;
}
int main()
{
    int i , j , k , l , n , x1 , y1 , x2 , y2 ;
    double x = 0 , ans = INF , temp , temp1 , temp2 ;
    scanf("%d", &n) ;
    memset(Map,0,sizeof(Map)) ;
    for(i = 1 ; i <= 8 ; i++)
    {
        for(j = 1 ; j <= 8 ; j++)
        {
            scanf("%d", &Map[i][j]) ;
            Map[i][j] += Map[i][j-1] ;
        }
        for(j = 1 ; j <= 8 ; j++)
            Map[i][j] += Map[i-1][j] ;
    }
    /*for(i = 0 ; i <= 8 ; i++)
    {
        for(j = 0 ; j <= 8 ; j++)
            printf("%d ", Map[i][j]) ;
        printf("\n") ;
    }*/
    x = Map[8][8]*1.0/n ;
    //printf("%lf\n", x) ;
    for(i = 0 ; i <= n ; i++)
        for(j = 0 ; j <= 8888 ; j++)
            dp[i][j] = INF ;
    dp[1][88] = (Map[8][8]*1.0 - x) * (Map[8][8]*1.0 - x) ;
    for(i = 1 ; i < n ; i++)
    {
        for(j = 0 ; j <= 8888 ; j++)
        {
            x1 = j/1000%10 ;
            y1 = j/100%10 ;
            x2 = j/10%10 ;
            y2 = j%10 ;
            temp = f(x1,y1,x2,y2,x) ;
            for(k = x1+1 ; k < x2 ; k++)
            {
                temp1 = f(x1,y1,k,y2,x) ;
                temp2 = f(k,y1,x2,y2,x) ;
                l = x1*1000+y1*100+k*10+y2 ;
                if( dp[i+1][l] > dp[i][j] - temp + temp1 + temp2 )
                    dp[i+1][l] = dp[i][j] - temp + temp1 + temp2 ;
                l = k*1000+y1*100+x2*10+y2 ;
                if( dp[i+1][l] > dp[i][j] - temp + temp1 + temp2 )
                    dp[i+1][l] = dp[i][j] - temp + temp1 + temp2 ;
            }
            for(k = y1+1 ; k < y2 ; k++)
            {
                temp1 = f(x1,y1,x2,k,x) ;
                temp2 = f(x1,k,x2,y2,x) ;
                l = x1*1000+y1*100+x2*10+k ;
                if( dp[i+1][l] > dp[i][j] - temp + temp1 + temp2 )
                    dp[i+1][l] = dp[i][j] - temp + temp1 + temp2 ;
                l = x1*1000+k*100+x2*10+y2 ;
                if( dp[i+1][l] > dp[i][j] - temp + temp1 + temp2 )
                    dp[i+1][l] = dp[i][j] - temp + temp1 + temp2 ;
            }
        }
    }
    for(j = 0 ; j <= 8888 ; j++)
        ans = min(ans,dp[n][j]) ;
    printf("%.3lf\n", sqrt(ans/(n*1.0))) ;
    return 0;
}

时间: 2024-08-23 01:56:16

poj1191--棋盘分割(dp)的相关文章

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

棋盘分割 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16263   Accepted: 5812 Description 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘.(每次切割都只能沿着棋盘格子的边进行) 原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和.现在需要把棋盘按上述规

POJ1191——棋盘分割

棋盘分割 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12456   Accepted: 4389 Description 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘.(每次切割都只能沿着棋盘格子的边进行) 原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和.现在需要把棋盘按上述规

NOI1999 JZYZOJ1289 棋盘分割 dp 方差的数学结论

http://172.20.6.3/Problem_Show.asp?id=1289 除了下标一坨一坨屎一样挺恶心其他都还挺容易的dp,这道题才发现scanf保留小数位是四舍五入的,惊了. f[k][x1][y1][x2][y2] 嗯写的时候猜错结论了,本来以为是求下属分配方案中平方和与平均数平方*k的差最小的方案赋给f,没想到是直接找最小的. 代码 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream>

【POJ 1191】 棋盘分割(DP)

[POJ 1191] 棋盘分割(DP) Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 13811   Accepted: 4917 Description 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘.(每次切割都只能沿着棋盘格子的边进行) 原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分

POJ 1191 棋盘分割

棋盘分割 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11938   Accepted: 4207 Description 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘.(每次切割都只能沿着棋盘格子的边进行) 原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和.现在需要把棋盘按上述规

棋盘分割(记忆化搜索)

棋盘分割 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 501    Accepted Submission(s): 248 Problem Description 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘.

NOI 193棋盘分割.cpp

193:棋盘分割 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  65536kB 描述 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘.(每次切割都只能沿着棋盘格子的边进行)原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和.现在需要把棋盘按上述规则分割成n块矩形棋盘,并使各矩形棋盘总分的均方差最小.均方差,其中平均值,xi为第i块矩形棋盘的

POJ1991 NOI1999棋盘分割

棋盘分割 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 15581   Accepted: 5534 Description 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘.(每次切割都只能沿着棋盘格子的边进行) 原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和.现在需要把棋盘按上述规

POJ百炼——1191棋盘分割

1191:棋盘分割 总时间限制: 1000ms 内存限制: 65536kB 描述 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘.(每次切割都只能沿着棋盘格子的边进行)原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和.现在需要把棋盘按上述规则分割成n块矩形棋盘,并使各矩形棋盘总分的均方差最小.均方差,其中平均值,xi为第i块矩形棋盘的总分.请编程对给出的棋盘及