C++---区间DP---棋盘分割(每日一道算法2023.5.2)

news2024/10/7 3:14:18

注意事项:
涉及到"矩阵/二维前缀和"的一些知识,建议先理解那篇文章。

题目:
将一个 8×8 的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了 (n−1) 次后,连同最后剩下的矩形棋盘共有 n 块矩形棋盘。(每次切割都只能沿着棋盘格子的边进行)
请添加图片描述

原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和。
现在需要把棋盘按上述规则分割成 n 块矩形棋盘,并使各矩形棋盘总分的均方差最小。

均方差 请添加图片描述,其中平均值 请添加图片描述,xi 为第 i 块矩形棋盘的总分。

请编程对给出的棋盘及 n,求出均方差的最小值。

输入格式
第 1 行为一个整数 n。
第 2 行至第 9 行每行为 8 个小于 100 的非负整数,表示棋盘上相应格子的分值。每行相邻两数之间用一个空格分隔。

输出格式
输出最小均方差值(四舍五入精确到小数点后三位)。

数据范围
1<n<15

输入:
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
输出:
1.633
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;

const int N = 15, M = 9, INF = 1e9;
int n, m = 8;                   //n为最多分割的次数,m固定为棋盘的长宽8*8
int s[M][M];                    //s数组是棋盘的二维前缀和,用来快捷的求出一个区域内的值的总和
double f[M][M][M][M][N];        //f[x1][y1][x2][y2][k]
double X;                       //大写X表示均方差公式中的X拔

double get(int x1, int y1, int x2, int y2) {        //得到(x1, y1)为左上点,(x2, y2)为右下点的区间内的值
    double sum = (s[x2][y2] - s[x1-1][y2] - s[x2][y1-1] + s[x1-1][y1-1]) - X;
    return sum*sum / n;
}

double dp(int x1, int y1, int x2, int y2, int k) {  //区间dp
    double &v = f[x1][y1][x2][y2][k];
    if (v >= 0) return v;                       //记忆化搜索,如果当前区间已被计算,直接返回值即可
    if (k == 1) return get(x1, y1, x2, y2);     //如果当前k为1说明是最后一刀,那么就直接返回(x1, y1)(x2, y2)这个区间内的值即可

    //v设为正无穷,因为要取min
    v = INF;
    for (int i = x1; i<x2; i++) {   //枚举x1到x2之间的每一个分割线
        v = min(v, dp(x1, y1, i, y2, k-1) + get(i+1, y1, x2, y2));
        v = min(v, dp(i+1, y1, x2, y2, k-1) + get(x1, y1, i, y2));
    }
    for (int i = y1; i<y2; i++) {   //枚举y1到y2之间的每一个分割线
        v = min(v, dp(x1, y1, x2, i, k-1) + get(x1, i+1, x2, y2));
        v = min(v, dp(x1, i+1, x2, y2, k-1) + get(x1, y1, x2, i));
    }
    return v;
}

int main() {
    //读入,处理二维前缀和
    cin >> n;
    for (int i = 1; i<=m; i++) {
        for (int j = 1; j<=m; j++) {
            cin >> s[i][j];
            s[i][j] = s[i][j] + s[i-1][j] + s[i][j-1] - s[i-1][j-1];
        }
    }

    //f初始化为负数
    memset(f, -1, sizeof f);
    X = (double)s[m][m] / n;
    
    //输出小数点3位,并把算出的最小值开方
    printf("%.3lf", sqrt(dp(1, 1, 8, 8, n)));
    return 0;
}

思路:
思路很简单,其实就是枚举棋盘的所有分割方式,
具体为每次对棋盘进行一次横切或竖切,将棋盘分成两块矩形的子棋盘,
分割完一次后,我们可以选择两个子棋盘中的一个再继续递归操作,
直到分割次数k用完或已经不能再切割为止。

还是经典的y式dp分析法
1.状态表示
f[x1][y1][x2][y2][k]:
以(x1, y1)为左上角,(x2, y2)为右下角的区域,分割k次的所有方案,
属性为Min(最小均方差)。

2.状态计算
枚举所有当前选取的区间的切分可能性:

1.横切,y1y2间的所有分界线k(切y轴)
上区间值:top = value(x1, y1, x2, k)
下区间值:bot = value(x1, k+1, x2, y2)

2.竖切,x1x2间的所有分界线k(切x轴)
左区间值:left = value(x1, y1, k, y2)
右区间值:right = value(k+1, y1, x2, y2)

注意这里横切和竖切是并列的关系而不是嵌套,因为横切了就不能竖切,竖切了就不能横切,只能取一种,Min(top, bot, left, right) 即为当前区间最小均方差。

如果有所帮助请给个免费的赞吧~有人看才是支撑我写下去的动力!

声明:
算法思路来源为y总,详细请见https://www.acwing.com/
本文仅用作学习记录和交流

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/483108.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

echarts数据可视化-动态柱状图

效果如下&#xff1a; 此处用的echarts柱状图为&#xff1a;Axis Align with Tick 本文的要讨论的内容&#xff1a; 1、柱状图样式修改 2、多数据的缩放展示 柱状图样式修改 // 数据 const city reactive([{ value: 335, name: 长沙 },{ value: 310, name: 武汉 },{ value: …

C++类和对象 ——构造函数

C拷贝构造函数详解 什么是拷贝构造函数&#xff1f;拷贝构造函数的特征默认拷贝构造函数为什么需要显示定义构造函数&#xff1f;拷贝构造函数的调用场景什么时候不需要自己定义拷贝构造函数 什么是拷贝构造函数&#xff1f; 在现实生活中&#xff0c;拷贝构造函数就好像我们上…

Linux服务器 容器化部署新版Jenkins

安装Docker 先安装yml yum install -y yum-utils device-mapper-persistent-data lvm2设置加速镜像&#xff08;阿里云镜像&#xff09; sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo安装docker yum -y install d…

智慧工厂人员定位系统源码,实现对工厂内的人车、物、料等的精确定位

智慧工厂人员定位系统源码 技术架构&#xff1a;Java vue spring boot 系统概述&#xff1a; 采用UWB定位技术&#xff0c;通过在厂区内布设一定数量的定位基站&#xff0c;实时精确地定位员工、车辆、物品上微标签位置&#xff0c;零延时地将人、车、物的位置信息显示在工厂…

数据结构(六)—— 二叉树(2)遍历

文章目录 递归三要素一、深度优先遍历&#xff08;前中后序&#xff09;1.1 递归遍历1.1.1 前序&#xff08;中左右&#xff09;1.1.2 中序&#xff08;左中右&#xff09;1.1.3 后序&#xff08;左右中&#xff09; 1.2 迭代遍历1.2.1 前序1.2.2 后序1.2.3 中序 二、广度优先遍…

创建前、中、后序二叉树

创建前、中、后序二叉树 一、前序二叉树二、中序二叉树二、后序二叉树 一、前序二叉树 规则&#xff1a;根->左->右 前序遍历结果&#xff1a;ABCDEFGHK 二、中序二叉树 规则&#xff1a;左->根->右 中序遍历结果&#xff1a;ABCDEFG 二、后序二叉树 规则&a…

浅尝ChatGPT使用之Python字典嵌套排序

一、背景 所负责的项目从v1.0升级到v2.0之后&#xff0c;发送到kafka的Json数据字段顺序和内容有所改变&#xff0c; v1.0版本推送数据样例&#xff1a; {"name": "小王子","author": "安托万德圣-埃克苏佩里&#xff08;1900-1944&#…

1.Hive基础

1.简介 作用&#xff1a;将结构化数据映射为一张表&#xff0c;并提供类sql功能 本质&#xff1a;将HQL转化成MapReduce程序 &#xff08;1&#xff09;Hive处理的数据存储在HDFS ​ &#xff08;2&#xff09;Hive分析数据底层的实现是MapReduce ​ &#xff08;3&#x…

keil5固件库版本的工程建立

keil5固件库版本的工程建立 一、一个文件夹&#xff0c;如图再建立4个文件夹 二、准库往上图四个文件夹里粘贴 从标准库里面把Libraries里面的两个文件夹全部复制到新建文件夹Libraries里面 三、来对新建的Libraries里面的两个文件夹进行更改 STM32F10x_StdPeriph_Driver这个…

ajax与json

title: 15 ajax与json date: ‘2023-3-29’ 从一个例子开始 传统的方式进行前后端交互是什么样子的&#xff1f; <% page language"java" contentType"text/html; charsetUTF-8"pageEncoding"UTF-8"%> <html> <head><me…

python cms建站教程:Wagtail建站(二、修改主页与自定义后台管理)

不得不说python的中文cms建站教程实在是太少了&#xff0c;直接用Django/Flask这样的框架从头开始写又实在是有点麻烦&#xff0c;自己摸索着写一点使用Wagtail建站的方法&#xff0c;仅供参考。Wagtail是一款基于Django框架的CMS建站工具&#xff0c;可以为你的网站提供一个比…

点赋科技:本地生活,如何开启复苏之路

目前&#xff0c;全球经历这场前所未有的疫情大流行已经结束&#xff0c;尽管许多国家和地区的经济和社会都受到了影响。然而&#xff0c;做好本地生活的复苏规划和推进&#xff0c;将有助于在疫情之后尽快走出经济低迷期&#xff0c;恢复社会活动和生活体验。点赋科技将阐述如…

初识MySQL数据库——“MySQL数据库”

各位CSDN的uu们你们好呀&#xff0c;小雅兰好久没有更文啦&#xff0c;确实是心有余而力不足&#xff0c;最近学习的内容太难了&#xff0c;这篇博客又是小雅兰的新专栏啦&#xff0c;主要介绍的是一些MySQL数据库的知识点&#xff0c;下面&#xff0c;让我们进入初识MySQL数据…

【黑马程序员 C++教程从0到1入门编程】【笔记8】 泛型编程——模板

https://www.bilibili.com/video/BV1et411b73Z?p167 C泛型编程是一种编程范式&#xff0c;它的核心思想是编写通用的代码&#xff0c;使得代码可以适用于多种不同的数据类型。 而模板是C中实现泛型编程的一种机制&#xff0c;它允许我们编写通用的代码模板&#xff0c;然后在需…

静态成员与友元函数

有缘 class Point {private:double x, y; public:Point(double xx, double yy) ;friend double Distance(Point &a, Point &b); };Point::Point(double xx, double yy) {x xx;y yy; }double Distance(Point &a, Point &b) {return sqrt(pow(a.x - b.x, 2) p…

【STM32CubeMX】F103定时中断

前言 本文记录下我学习STM32CubeMX时的流程&#xff0c;方便以后回忆。系统板是基于STM32F103C6T6。本章记录定时中断。 步骤 实验目标&#xff1a;利用定时器TIM2装载计数&#xff0c;1S的定时中断事件&#xff0c;事件是LED(PC13)的亮灭。 配置时钟源为外部高速源(HSE),流程…

MinIO分布式存储服务

一、前言 最近项目中使用到了MinIO的分布式存储系统&#xff0c;记录一下Minio服务的相关概念以及使用方法。 二、基本概念 MinIO 对象存储系统是为海量数据存储、人工智能、大数据分析而设计&#xff0c;基于Apache License v2.0 开源协议的对象存储系统&#xff0c;它完全…

【五一创作】【软考:软件设计师】 5 计算机组成与体系结构(三)认证技术 | 计算机可靠性

欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 本文收录于软考中级&#xff1a;软件设计师系列专栏,本专栏服务于软考中级的软件设计师考试,包括不限于知识点讲解与真题讲解两大部分,并且提供电子教材与电子版真题,关注私聊即可 …

C++入门(保姆级教程)

目录 一、C关键字 二、命名空间 2.1 C语言中的命名冲突 2.2 C中命名空间 2.2.1 命名空间的定义 2.2.2 命名空间的特性 2.2.3 命名空间的使用 2.2.4 补充知识 2.2.4 C库的命名空间 三、C中的输入&输出 四、缺省参数 4.1 定义 4.2 缺省参数的分类 4.2.1 全缺…

Nacos—简述、注册中心、配置中心

目录 什么是Nacos&#xff1f; 什么是注册中心&#xff1f; 什么是配置中心&#xff1f; 什么是服务管理平台&#xff1f; Nacos的关键特性包括&#xff08;有点&#xff09;有哪些&#xff1f; 作用&#xff08;为什么要使用&#xff09;&#xff1f; 注册中心演变过程 …