zoukankan      html  css  js  c++  java
  • 菜板 动态规划


    将一个8*8的棋盘进行例如以下切割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,

    再将剩下的部分继续如此切割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共同拥有n块矩形棋盘。

    (每次分割都仅仅能沿着棋盘格子的边进行) 


    原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和。

    如今须要把棋盘按上述规则切割成n块矩形棋盘,并使各矩形棋盘总分的均方差最小。 
    均方差,当中平均值。xi为第i块矩形棋盘的总分。

     

    请编程对给出的棋盘及n。求出O'的最小值。 


    #include <iostream>
    #include <cstring>
    #include <cmath>
    #include <iomanip>
    #include <fstream>
    using namespace std;
    
    const int MAX = 1 << 30;
    
    int chessboard[9][9];
    int sums[9][9][9][9];
    double DP[20][9][9][9][9];
    
    int N;
    
    int main(){
    
        double totals = 0.0;
        double avg = 0.0;
    
        memset( chessboard, 0, sizeof( chessboard ) );
        memset( sums,       0, sizeof( sums ) );
    
        //fstream fin( "test.txt" );
        cin >> N;
    
        for( int i = 1; i <= 8; ++i ){
            for( int j = 1; j <= 8; ++j ){
                cin >> chessboard[i][j];
                sums[i][j][i][j] = chessboard[i][j];
                totals += chessboard[i][j];
                chessboard[i][j] += chessboard[i - 1][j] + chessboard[i][j - 1] - chessboard[i - 1][j - 1];
            }
        }
    
        avg = totals / ( N * 1.0 );
    
        for( int x1 = 1; x1 <= 8; ++x1 ){
            for( int y1 = 1; y1 <= 8; ++y1 ){
                for( int x2 = x1; x2 <= 8; ++x2 ){
                    for( int y2 = y1; y2 <= 8; ++y2 ){
                        sums[x1][y1][x2][y2] = chessboard[x2][y2] - chessboard[x1 - 1][y2] -
                                               chessboard[x2][y1 - 1] + chessboard[x1 - 1][y1 - 1];
                        DP[0][x1][y1][x2][y2] = sums[x1][y1][x2][y2] * sums[x1][y1][x2][y2];
                    }
                }
            }
        }
    
        for( int k = 1; k <= N - 1; ++k ){
            for( int x1 = 1; x1 <= 8; ++x1 ){
                for( int y1 = 1; y1 <= 8; ++y1 ){
                    for( int x2 = x1; x2 <= 8; ++x2 ){
                        for( int y2 = y1; y2 <= 8; ++y2 ){
    
                            DP[k][x1][y1][x2][y2] = MAX;
    
                            for ( int mid = x1; mid < x2; ++mid ){
                                DP[k][x1][y1][x2][y2] = min( DP[k][x1][y1][x2][y2],
                                                             DP[0][x1][y1][mid][y2] + DP[k - 1][mid + 1][y1][x2][y2] );
                                DP[k][x1][y1][x2][y2] = min( DP[k][x1][y1][x2][y2],
                                                             DP[k - 1][x1][y1][mid][y2] + DP[0][mid + 1][y1][x2][y2] );
                            }
    
                            for( int mid = y1; mid < y2; ++mid ){
                                DP[k][x1][y1][x2][y2] = min( DP[k][x1][y1][x2][y2],
                                                             DP[0][x1][y1][x2][mid] + DP[k - 1][x1][mid + 1][x2][y2] );
                                DP[k][x1][y1][x2][y2] = min( DP[k][x1][y1][x2][y2],
                                                             DP[k - 1][x1][y1][x2][mid] + DP[0][x1][mid + 1][x2][y2] );
                            }
                        }
                    }
                }
            }
        }
    
        double ans = DP[N - 1][1][1][8][8] / ( N * 1.0 ) - avg * avg;
        cout << setprecision(3) << fixed << sqrt(ans) << endl;
    
        return 0;
    }
    


    版权声明:本文博主原创文章。博客,未经同意不得转载。

  • 相关阅读:
    牛客小白月赛-鲲
    HDU-1069 Monkey and Banana
    HDU-1159 Common Subsequence
    Python3-提高效率的方法
    Python3-ORM-Sqlalchemy
    redis端口6379的由来
    Linux环境下的network IO
    Yii2-设置和获取、删除Cookies空值分析(有代码)
    PHP中的运算符---位运算符、递增递减运算符、三元运算符、字符串运算符、数组运算符、类型运算符、错误控制运算符
    redis的五种存储类型的具体用法
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4792748.html
Copyright © 2011-2022 走看看