• poj 1191 棋盘切割 (压缩dp+记忆化搜索)


    一,题意:

    中文题

    二。分析:

    主要利用压缩dp与记忆化搜索思想

    三,代码:

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <math.h>
    using namespace std;
    const int Big=20000000;
    int Mat[10][10];
    int N;
    int sum[10][10];
    int dp[20][10][10][10][10];
    void unit()
    {//求和用sum[i][j]表示ij到左上角的和
        int total;
        for(int i=1; i<=8; i++)
            for(int j=1; j<=8; j++)
            {
                total=Mat[i][j];
                int x_1,y_1;
                x_1=i-1;
                y_1=j-1;
                if(x_1>0)
                    total+=sum[x_1][j];
                if(y_1>0)
                    total+=sum[i][y_1];
                if(x_1>0&&y_1>0)
                    total-=sum[x_1][y_1];
                sum[i][j]=total;
            }
    }
    
    int account(int x_1,int y_1,int x_2,int y_2)
    {//求(x_1,y_1)到(x_2。y_2)区间和
        int total=sum[x_2][y_2];
        int x_3,y_3;
        x_3=x_1-1;
        y_3=y_1-1;
        if(x_3>0)
            total-=sum[x_3][y_2];
        if(y_3>0)
            total-=sum[x_2][y_3];
        if(x_3>0&&y_3>0)
            total+=sum[x_3][y_3];
        return total*total;
    }
    
    int solve(int k,int x_1,int y_1,int x_2,int y_2)
    {//记忆化dp
        if(dp[k][x_1][y_1][x_2][y_2]!=-1)
            return dp[k][x_1][y_1][x_2][y_2];
        if(k==1)
            return dp[k][x_1][y_1][x_2][y_2]=account(x_1,y_1,x_2,y_2);
        if(k>1)
        {
            int Min=Big;
            for(int i=y_1;i<y_2;i++)
            {//横向分割
                int first=account(x_1,y_1,x_2,i);
                int second=account(x_1,i+1,x_2,y_2);
                first+=solve(k-1,x_1,i+1,x_2,y_2);
                second+=solve(k-1,x_1,y_1,x_2,i);
                if(first>second)
                    first=second;
                if(Min>first)
                    Min=first;
            }
            for(int j=x_1;j<x_2;j++)
            {//纵向分割
                int first=account(x_1,y_1,j,y_2);
                int second=account(j+1,y_1,x_2,y_2);
                first+=solve(k-1,j+1,y_1,x_2,y_2);
                second+=solve(k-1,x_1,y_1,j,y_2);
                if(first>second)
                    first=second;
                if(Min>first)
                    Min=first;
            }
            return dp[k][x_1][y_1][x_2][y_2]=Min;
        }
        return dp[k][x_1][y_1][x_2][y_2]=Big;
    }
    
    int main()
    {
        while(scanf("%d",&N)!=EOF)
        {
            double total=0.0;
            for(int i=1; i<=8; i++)
                for(int j=1; j<=8; j++)
                {
                     scanf("%d",&Mat[i][j]);
                     total+=Mat[i][j];
                }
            unit();
            memset(dp,-1,sizeof(dp));
             total=(total/N)*(total/N);
            double key=solve(N,1,1,8,8);
            key=key/N;
           key=sqrt(key-total);
           printf("%0.3f
    ",key);
        }
        return 0;
    }
    


  • 相关阅读:
    微信网页授权登录(公众号)
    FastDFS:搭建文件管理系统
    第11章 分布式服务跟踪: Spring Cloud Sleuth
    第十章 消息驱动的微服务: Spring Cloud Stream
    第九章 消息总线: Spring Cloud Bus
    第八章 分布式配置中心:Spring Cloud Config
    体验Impress.js
    我擦,惊呆了惊呆了!!!微软这次推了个好东西啊
    化繁为简,无需后端。巧用Yql+rss,搭建我的个人网站
    PuTTY?Bash?Out了!!!终端应该这么玩~
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/7069771.html
Copyright © 2020-2023  润新知