随笔 - 87  文章 - 279  trackbacks - 0
<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

潜心看书研究!

常用链接

留言簿(19)

随笔分类(81)

文章分类(89)

相册

ACM OJ

My friends

搜索

  •  

积分与排名

  • 积分 - 214376
  • 排名 - 116

最新评论

阅读排行榜

评论排行榜

棋盘分割
Time Limit:1000MS  Memory Limit:10000K
Total Submit:490 Accepted:194

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
Noi 99

#include  < iostream >
#include 
< cstdlib >
#include 
< cmath >
using   namespace  std;

const   int  INF  =   2000000000 ;
int  f[ 9 ][ 9 ][ 9 ][ 9 ][ 15 ];
int  s[ 9 ][ 9 ][ 9 ][ 9 ];
int  d[ 9 ][ 9 ];

void  init()
{
    
int  x1, y1, x2, y2;
    
int  i, j;
    
int  sum;
    
for  (x1 = 1 ; x1 <= 8 ; x1 ++ )
        
for  (y1 = 1 ; y1 <= 8 ; y1 ++ )
            
for  (x2 = x1; x2 <= 8 ; x2 ++ )
                
for  (y2 = y1; y2 <= 8 ; y2 ++ )
                
{
                    sum 
=   0 ;
                    
for  (i = x1; i <= x2; i ++ )
                        
for  (j = y1; j <= y2; j ++ )
                            sum 
+=  d[i][j];
                    s[x1][y1][x2][y2] 
=  sum;
                    f[x1][y1][x2][y2][
1 =  sum  *  sum;
                }

}

int  main()
{

    
int  n;
    
int  i, j, k;
    
int  x1, y1, x2, y2;
    
int  a, b;
    
int  t, tmp;
    
double  p  =   0 ;

    scanf(
" %d " & n);
    
    
for  (i = 1 ; i <= 8 ; i ++ )
        
for  (j = 1 ; j <= 8 ; j ++ )
        
{
            scanf(
" %d " & d[i][j]);
            p 
+=  d[i][j];
        }


    p 
/=  n;
//     cout << "?? "<< p << endl;

    init();

    
for  (k = 2 ; k <= n; k ++ )
    
{
        
for  (x1 = 1 ; x1 <= 8 ; x1 ++ )
            
for  (y1 = 1 ; y1 <= 8 ; y1 ++ )
                
for  (x2 = x1; x2 <= 8 ; x2 ++ )
                    
for  (y2 = y1; y2 <= 8 ; y2 ++ )
                    
{
                        tmp 
=  INF;
                        
// 竖切
                         for  (a = x1; a < x2; a ++ )
                        
{
                            t 
=  min(f[x1][y1][a][y2][k - 1 ] + s[a + 1 ][y1][x2][y2] * s[a + 1 ][y1][x2][y2]
                                , f[a
+ 1 ][y1][x2][y2][k - 1 ] + s[x1][y1][a][y2] * s[x1][y1][a][y2]);
                            
if  (tmp  >  t) 
                                tmp 
=  t;
                        }

                        
// 横切
                         for  (b = y1; b < y2; b ++ )
                        
{
                            t 
=  min(f[x1][y1][x2][b][k - 1 ] + s[x1][b + 1 ][x2][y2] * s[x1][b + 1 ][x2][y2]
                                , f[x1][b
+ 1 ][x2][y2][k - 1 ] + s[x1][y1][x2][b] * s[x1][y1][x2][b]);
                            
if  (tmp  >  t)
                                tmp 
=  t;
                        }

                        
                        f[x1][y1][x2][y2][k] 
=  tmp;
                    }

    }

    printf(
" %.3f\n " , sqrt( double (f[ 1 ][ 1 ][ 8 ][ 8 ][n]) / double (n) - p * p));
    
return   0 ;
}
posted on 2006-09-08 22:57 阅读(1291) 评论(0)  编辑 收藏 引用 所属分类: ACM题目

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理