zoukankan      html  css  js  c++  java
  • POJ 1191 棋盘分割【区间类DP】

    http://poj.org/problem?id=1191

    1>根据公式化简:

    其中后者是一个已知数。求均方差的最小值就是求出个个棋盘内各数值的平方和最小值。

    2>棋盘分割分四种情况:

    竖切(左不动),竖切(右不动),横切(上不动),横切(下不动);

    3>状态转移方程:

    f(i, x1, y1, x2, y2)表示以(x1, y1),(x2, y2)为四边形对角线的棋盘切割成i块的各块值总平方的最小值;

    D(x1, y1, x2, y2)表示棋盘的总分

     

                       _____________ 

                       | f(i-1, x1, a+1, x2, y2)+D(x1, y1, x2, a)   [横切(上不动)]

                       | f(i-1, x1,y1, x2, a)+D(x1, a+1, x2, y2)   [横切(下不动)

    f(i, x1, y1, x2, y2)=min| f(i-1,b+1, y1, x2, y2)+D(x1, y1, b1, y2)  [竖切(左不动)]

                       | f(i-1, x1, y1, b, y2)+D(b+1, y1, x2, y2)   [竖切(右不动)]

                       ______________

    4>其中的a, b是进行枚举的值。先预处理Dx1, y1, x2, y2)

    代码如下:

    View Code
    /**
    *  POJ 1191 棋盘分割
    */
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    int a[9][9], F[15][9][9][9][9];
    int minx(int a1, int a2, int a3)
    {
        int minnum=99999999;
        if(a1<minnum) minnum=a1;
        if(a2<minnum) minnum=a2;
        if(a3<minnum) minnum=a3;
        return minnum;
    }
    int get(int x1,int y1,int x2,int y2)          //用来计算分割出来块的总分 
    {
       return a[x2][y2]-a[x2][y1-1]-a[x1-1][y2]+a[x1-1][y1-1];
    }
    int main()
    {
        int n, i, j, x1, y1, x2, y2, aa, b;
        while(scanf("%d", &n)!=EOF)
        {
            memset(F, 0, sizeof(F));
            memset(a, 0, sizeof(a));
            for(i=1; i<=8; i++)
               for(j=1; j<=8; j++)
               {
                   scanf("%d",&a[i][j]);
                   a[i][j]=a[i][j]+a[i-1][j]+a[i][j-1]-a[i-1][j-1];
               }
            for(i=1; i<=n; i++)
            for(x1=1; x1<=8; x1++)
            for(y1=1; y1<=8; y1++)
            for(x2=1; x2<=8; x2++)
            for(y2=1; y2<=8; y2++)
            {
                if(i==1||x1==x2||y1==y2)
                {
                     F[i][x1][y1][x2][y2]=get(x1, y1, x2, y2)*get(x1, y1, x2, y2);
                     continue;
                }
                int t1=99999999;
                for(aa=y1; aa<y2; aa++)
                    t1=minx(t1, F[i-1][x1][aa+1][x2][y2]+get(x1, y1, x2, aa)*get(x1, y1, x2, aa),
                            F[i-1][x1][y1][x2][aa]+get(x1, aa+1, x2, y2)*get(x1, aa+1, x2, y2));
                for(b=x1; b<x2; b++)
                    t1=minx(t1, F[i-1][b+1][y1][x2][y2]+get(x1, y1, b, y2)*get(x1, y1, b, y2),
                            F[i-1][x1][y1][b][y2]+get(b+1, y1, x2, y2)*get(b+1, y1, x2, y2));
                F[i][x1][y1][x2][y2]=t1;
            }
            double tt=F[n][1][1][8][8]*1.0/n-pow(a[8][8]*1.0/n, 2.0);
            printf("%.3lf\n", sqrt(tt));
        }
        return 0;
    }
  • 相关阅读:
    软件测试人员的年终绩效考核怎么应对
    收藏
    顶踩组件 前后两版
    订阅组件
    hdu 1963 Investment 完全背包
    hdu 4939 Stupid Tower Defense 动态规划
    hdu 4405 Aeroplane chess 动态规划
    cf 414B Mashmokh and ACM 动态规划
    BUPT 202 Chocolate Machine 动态规划
    hdu 3853 LOOPS 动态规划
  • 原文地址:https://www.cnblogs.com/Hilda/p/2939688.html
Copyright © 2011-2022 走看看