【动态规划题目讲解】AGC026D - Histogram Coloring

2024-02-25 23:28

本文主要是介绍【动态规划题目讲解】AGC026D - Histogram Coloring,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

[ A G C 026 D ] H i s t o g r a m C o l o r i n g \mathrm{[AGC026D] Histogram\ Coloring} [AGC026D]Histogram Coloring

D e s c r i p t i o n \mathrm{Description} Description

给定 N N N 列的网格,每列高为 h i h_i hi,将每个格子染色成红色或蓝色,使得每个 2 × 2 2\times 2 2×2 的区域都恰好有两个蓝格子和两个红格子,求方案数。

S o l u t i o n \mathrm{Solution} Solution

为了小编书写方便,令 1 1 1 为红, 0 0 0 为蓝(反过来也无所谓)

简化版

思考一下如果 h i h_i hi 全部相等,怎么做呢?(比如说,给个 20 p t s 20\mathrm{pts} 20pts 的部分分)

那么,其实就相当于给定了一个矩形,此时对于矩形的最后一行进行分类讨论:

最后一行有 2 2 2 0 0 0,那么上一行对应位置只能填 2 2 2 1 1 1,对应这别的位置也能相应的填好

所以,发现其实是一个翻转操作,但是这里的前提是下面有一对连续的 0 0 0,那么才会固定上一行,那如果最后一行是 01 01 01 交替呢?

那么,上一行你可以发现有 2 2 2 种填法: 010101 … 010101\dots 010101 1010101 … 1010101\dots 1010101

这样对于每一行都会分成 2 2 2 种,那么最后的方案数应该就是 2 h i 2^{h_i} 2hi(最后一行也是 2 2 2 种)。

而对于第 1 1 1 种情况:底部的状态有 2 n 2^n 2n 种填法,而上面会固定,所以不会再有更多的状态

但是,这 2 2 2 种会算重,即 0101 … 0101\dots 0101 1010 … 1010\dots 1010 会被算 2 2 2 次,所以最终的方案数为 2 n + 2 h i − 2 2^n+2^{h_i}-2 2n+2hi2


那么,这是简化版的做法,不过可以借鉴简化版的思路来解决这道问题。

这道题无非就是 h i h_i hi 不相同了,比如说形状如下图所示:( h i h_i hi 可能为 0 0 0

那么,对于这个图,考虑到每次可以划分成一个矩形,考虑子问题,比如说:

只考虑到当前最矮的那个方块,那么下面其实就是一个矩形,然后上面就会分成 2 2 2 个部分,即为两个子问题,那么就可以设计 DP 了!较为自然的想到设 f l , r f_{l,r} fl,r 表示区间 l ∼ r l\sim r lr 的方案数,不过只设这些可以吗?其实是不可以的,你会发现还有划分的高度,所以还要存一维高度,以及当前是不是 01 01 01 交替。所以,总结一下,设 f l , r , h , 0 / 1 f_{l,r,h,0/1} fl,r,h,0/1 表示区间 l ∼ r l\sim r lr,当前划分高度为 h h h,是/不是 01 01 01 交替。( 0 0 0 表示是, 1 1 1 表示不是)

那么,考虑转移: f l , r , h , 0 = f l , p − 1 , h p , 0 × f p + 1 , r , h p , 0 × 2 h p − h f_{l,r,h,0}=f_{l,p-1,h_p,0}\times f_{p+1,r,h_p,0}\times 2^{h_p-h} fl,r,h,0=fl,p1,hp,0×fp+1,r,hp,0×2hph

其中 p p p 为当前最低方块的位置,即左边的方案数乘右边的方案数,由于划分出的矩形是 01 01 01 交替的,所以每行都有 2 2 2 种,总共就是 2 h p − h 2^{h_p-h} 2hph 种。

下面考虑不是 01 01 01 交替的转移:

如果左侧是 01 01 01 交替,右侧是 01 01 01 交替,那么总共有 6 6 6 种,因为中间 p p p 位置要想让区间 l ∼ r l\sim r lr 不是 01 01 01 交替,那么必须和左侧或右侧中有一个是相等的。(这里就不一一列举了)

如果左侧 01 01 01 交替,右侧不是 01 01 01 交替,那么左侧可以是 01 01 01 10 10 10 p p p 位置有 2 2 2 种选择,所以是 4 4 4 种。

如果左侧不是 01 01 01 交替,右侧是 01 01 01 交替,那么同理可得是 4 4 4 种。

如果左侧和右侧都不是 01 01 01 交替,那么只能 p p p 点取 0 / 1 0/1 0/1,是 2 2 2 种。

综上所述:令 l 0 = f l , p − 1 , h p , 0 , l 1 = f l , p − 1 , h p , 1 , r 0 = f p + 1 , r , h p , 0 , r 1 = f p + 1 , r , h p , 1 l_0=f_{l,p-1,h_p,0},l_1=f_{l,p-1,h_p,1},r_0=f_{p+1,r,h_p,0},r_1=f_{p+1,r,h_p,1} l0=fl,p1,hp,0,l1=fl,p1,hp,1,r0=fp+1,r,hp,0,r1=fp+1,r,hp,1

则, f l , r , h , 1 = 6 l 0 r 0 + 4 l 0 r 1 + 4 l 1 r 0 + 2 l 1 r 1 f_{l,r,h,1}=6l_0r_0+4l_0r_1+4l_1r_0+2l_1r_1 fl,r,h,1=6l0r0+4l0r1+4l1r0+2l1r1


A c c p e t e d C o d e \mathrm{Accpeted\ Code} Accpeted Code

#include <bits/stdc++.h>
#define int long longusing namespace std;typedef pair<int, int> PII;
typedef long long LL;
typedef unsigned long long ull;const int SIZE = 1e2 + 10, MOD = 1e9 + 7;int N;
int H[SIZE];int ksm(int a, int b, int p)
{int Result = 1;while (b){if (b & 1) Result = Result * a % p;a = a * a % p;b >>= 1;}return Result;
}
int DP(int l, int r, int h, int k)
{if (l > r) return 1;if (l == r) return k ? 0 : ksm(2, H[l] - h, MOD);int Min = 1e18, P;for (int i = l; i <= r; i ++)if (H[i] < Min) Min = H[i], P = i;if (!k) return DP(l, P - 1, H[P], 0) * DP(P + 1, r, H[P], 0) % MOD * ksm(2, H[P] - h, MOD) % MOD;if (P == l) return 2 * (DP(P + 1, r, H[P], 0) + DP(P + 1, r, H[P], 1)) % MOD;if (P == r) return 2 * (DP(l, P - 1, H[P], 0) + DP(l, P - 1, H[P], 1)) % MOD;int L0 = DP(l, P - 1, H[P], 0), L1 = DP(l, P - 1, H[P], 1), R0 = DP(P + 1, r, H[P], 0), R1 = DP(P + 1, r, H[P], 1);return (6 * L0 % MOD * R0 % MOD + 4 * L1 * R0 % MOD + 4 * L0 * R1 % MOD + 2 * L1 * R1 % MOD) % MOD;
}signed main()
{cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);cin >> N;for (int i = 1; i <= N; i ++)cin >> H[i];cout << (DP(1, N, 0, 0) + DP(1, N, 0, 1)) % MOD << endl;return 0;
}

这篇关于【动态规划题目讲解】AGC026D - Histogram Coloring的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/747025

相关文章

Python使用国内镜像加速pip安装的方法讲解

《Python使用国内镜像加速pip安装的方法讲解》在Python开发中,pip是一个非常重要的工具,用于安装和管理Python的第三方库,然而,在国内使用pip安装依赖时,往往会因为网络问题而导致速... 目录一、pip 工具简介1. 什么是 pip?2. 什么是 -i 参数?二、国内镜像源的选择三、如何

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

Python itertools中accumulate函数用法及使用运用详细讲解

《Pythonitertools中accumulate函数用法及使用运用详细讲解》:本文主要介绍Python的itertools库中的accumulate函数,该函数可以计算累积和或通过指定函数... 目录1.1前言:1.2定义:1.3衍生用法:1.3Leetcode的实际运用:总结 1.1前言:本文将详

Java使用POI-TL和JFreeChart动态生成Word报告

《Java使用POI-TL和JFreeChart动态生成Word报告》本文介绍了使用POI-TL和JFreeChart生成包含动态数据和图表的Word报告的方法,并分享了实际开发中的踩坑经验,通过代码... 目录前言一、需求背景二、方案分析三、 POI-TL + JFreeChart 实现3.1 Maven

Java导出Excel动态表头的示例详解

《Java导出Excel动态表头的示例详解》这篇文章主要为大家详细介绍了Java导出Excel动态表头的相关知识,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录前言一、效果展示二、代码实现1.固定头实体类2.动态头实现3.导出动态头前言本文只记录大致思路以及做法,代码不进

vue基于ElementUI动态设置表格高度的3种方法

《vue基于ElementUI动态设置表格高度的3种方法》ElementUI+vue动态设置表格高度的几种方法,抛砖引玉,还有其它方法动态设置表格高度,大家可以开动脑筋... 方法一、css + js的形式这个方法需要在表格外层设置一个div,原理是将表格的高度设置成外层div的高度,所以外层的div需要

Redis的Zset类型及相关命令详细讲解

《Redis的Zset类型及相关命令详细讲解》:本文主要介绍Redis的Zset类型及相关命令的相关资料,有序集合Zset是一种Redis数据结构,它类似于集合Set,但每个元素都有一个关联的分数... 目录Zset简介ZADDZCARDZCOUNTZRANGEZREVRANGEZRANGEBYSCOREZ

Go中sync.Once源码的深度讲解

《Go中sync.Once源码的深度讲解》sync.Once是Go语言标准库中的一个同步原语,用于确保某个操作只执行一次,本文将从源码出发为大家详细介绍一下sync.Once的具体使用,x希望对大家有... 目录概念简单示例源码解读总结概念sync.Once是Go语言标准库中的一个同步原语,用于确保某个操

SpringBoot实现动态插拔的AOP的完整案例

《SpringBoot实现动态插拔的AOP的完整案例》在现代软件开发中,面向切面编程(AOP)是一种非常重要的技术,能够有效实现日志记录、安全控制、性能监控等横切关注点的分离,在传统的AOP实现中,切... 目录引言一、AOP 概述1.1 什么是 AOP1.2 AOP 的典型应用场景1.3 为什么需要动态插

VUE动态绑定class类的三种常用方式及适用场景详解

《VUE动态绑定class类的三种常用方式及适用场景详解》文章介绍了在实际开发中动态绑定class的三种常见情况及其解决方案,包括根据不同的返回值渲染不同的class样式、给模块添加基础样式以及根据设... 目录前言1.动态选择class样式(对象添加:情景一)2.动态添加一个class样式(字符串添加:情