Poj 1191 棋盘分割 简单的DP

棋盘分割
Time Limit: 1000MS
Memory Limit: 10000K
Total Submissions: 4494
Accepted: 1578

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
本题WA无数,原因是本题中存在一个令人十分郁闷的事情,同样的代码,如果提交G++那么便WA,如果提交C++就AC,原因是VC++中double的精度要大于G++中double的精度。害得我一遍一遍寻找是不是我丢失了某些特殊情况。总之一个字 囧~~
本题简单,说下思路。就是个DP,子问题记得加上刀数~~· Have fun!

#include <vector>
#include <cstdlib>
#include <memory.h>
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <set>
using namespace std;
long double t[8][8][8][8][20];
int all_sum[8][8][8][8];
int matrix[8][8];
int sum_the_matrix(int i,int j,int x,int y)
{
    if (all_sum[i][j][x][y] != 0)
    {
        return all_sum[i][j][x][y];
    }
    int h,v,k,l;
    int all = 0;
    for (h=i; h<=x;h++)
    {
        for (k=j;k<=y;k++)
        {
            all = all+matrix[h][k];
        }
    }
    all_sum[i][j][x][y] = all;
    return all_sum[i][j][x][y];
}
long double get_the_value(int i,int j,int x,int y,long double means,int times)
{
    
     if(t[i][j][x][y][times]!=-1.0)
     {
        return t[i][j][x][y][times];
     }
    if (i == 0&&j==0&&x==7&&y==0&&times==2)
    {
        int dfdf = i;
    }
     int all = sum_the_matrix(i,j,x,y);
     if (times == 0)
     {
         t[i][j][x][y][times] = (all-means)*(all-means);
         return t[i][j][x][y][times];
     }
     set<long double> min_d;
     int h,v,a,b,c;
     for (h=i ; h<x ; h++)//horizon

     {
            int xi = sum_the_matrix(h+1,j,x,y);
            if ((h-i+y-j)>=(times-1) )//xi is located at the button of the rectangle

            {
                min_d.insert((xi-means)*(xi-means)+get_the_value(i,j,h,y,means,times-1));
            }
            if ((x-h-1+y-j)>=(times-1))//xi is located at the top of the rectangle

            {
                min_d.insert((all-xi-means)*(all-xi-means)+get_the_value(h+1,j,x,y,means,times-1));
            }
     }
     for (v=j;v<y;v++)
     {
         int xi = sum_the_matrix(i,v+1,x,y);
         if ((x-i+y-v-1) >=(times-1))////xi is located at the left of the rectangle

         {
             min_d.insert((all-xi-means)*(all-xi-means)+get_the_value(i,v+1,x,y,means,times-1));
         }
         if ((x-i+v-j)>=(times-1))////xi is located at the right of the rectangle

         {
                min_d.insert((xi-means)*(xi-means)+get_the_value(i,j,x,v,means,times-1));
         }
     }
     t[i][j][x][y][times] = *min_d.begin();
     return t[i][j][x][y][times];

}
int main()
{

    int N,All_sum = 0;
    long double means = 0.0;
    int i ,j,x,y,u;
    memset(all_sum,0,sizeof(int)*8*8*8*8);
    for (i = 0;i <8;i++)
    {
        for (j = 0;j<8;j++)
        {
            for (x=0;x<8;x++)
            {
                for (y=0;y<8;y++)
                {
                    for (u=0;u<20;u++)
                    {
                        t[i][j][x][y][u] = -1.0;
                    }
                    
                }
            }
        }
    }
    cin>>N;
    for (i = 0; i <8 ;i++)
    {
        for (j= 0;j <8;j++)
        {
            cin>>matrix[i][j];
            All_sum = All_sum + matrix[i][j];
        }
    }
    means = (All_sum *1.0)/(N*1.0);
    printf("%.3lf\n",sqrt(get_the_value(0,0,7,7,means,N-1)/N*1.0));
    return 0;
}//ps 得提交C++






posted @ 2010-02-06 00:36  David Luo  阅读(440)  评论(0编辑  收藏  举报