zoukankan      html  css  js  c++  java
  • POJ 1191 棋盘分割(区间DP)题解

    题意:中文题面

    思路:不知道直接暴力枚举所有情况行不行。。。

    我们可以把答案转化为

    所以答案就是求xi2的最小值,那么我们可以直接用区间DP来写。设dp[x1][y1][x2][y2][k]为x1 y1 到 x2 y2 区间分割为k份的最下平方和,显然k = 1是就是区间和的平方。

    写了6层for,写出来自己都不信。。。

    交C++才过。。。

    代码:

    #include<cmath>
    #include<stack>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include <iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn = 10 + 10;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1000000007;
    int n;
    double w[maxn][maxn], dp[maxn][maxn][maxn][maxn][maxn], sum[maxn][maxn];
    double get(int x1, int y1, int x2, int y2){
        return sum[x2][y2] - sum[x2][y1 - 1] - sum[x1 - 1][y2] + sum[x1 - 1][y1 - 1];
    }
    int main(){
        scanf("%d", &n);
        memset(sum, 0, sizeof(sum));
        for(int i = 1; i <= 8; i++){
            for(int j = 1; j <= 8; j++){
                scanf("%lf", &w[i][j]);
                sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + w[i][j];
            }
        }
        double per = sum[8][8] / n;
        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++){
                        double ret = get(x1, y1, x2, y2);
                        dp[x1][y1][x2][y2][1] = ret * ret;
                    }
                }
            }
        }
        for(int k = 2; k <= n; 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[x1][y1][x2][y2][k] = INF;
                            for(int t = x1; t < x2; t++){
                                dp[x1][y1][x2][y2][k] = min(dp[x1][y1][x2][y2][k], dp[x1][y1][t][y2][1] + dp[t + 1][y1][x2][y2][k - 1]);
                                dp[x1][y1][x2][y2][k] = min(dp[x1][y1][x2][y2][k], dp[x1][y1][t][y2][k - 1] + dp[t + 1][y1][x2][y2][1]);
                            }
                            for(int t = y1; t < y2; t++){
                                dp[x1][y1][x2][y2][k] = min(dp[x1][y1][x2][y2][k], dp[x1][y1][x2][t][1] + dp[x1][t + 1][x2][y2][k - 1]);
                                dp[x1][y1][x2][y2][k] = min(dp[x1][y1][x2][y2][k], dp[x1][y1][x2][t][k - 1] + dp[x1][t + 1][x2][y2][1]);
                            }
                        }
                    }
                }
            }
        }
        printf("%.3lf
    ", sqrt(dp[1][1][8][8][n] / n - per * per));
        return 0;
    }
  • 相关阅读:
    结对项目电梯调度--设计模拟
    程序的单元测试
    一个文本单词统计的案例
    MFC vs2012 Office2013 读写excel文件
    Unix NetWork Programming(unix环境编程)——环境搭建(解决unp.h等源码编译问题)
    VMware三种上网模型
    矩阵求逆算法及程序实现(C++)
    unix环境高级编程基础知识之第四章
    2014阿里研发面试题目
    MFC下debug改成release版本出现问题及解决办法
  • 原文地址:https://www.cnblogs.com/KirinSB/p/10638906.html
Copyright © 2011-2022 走看看