【动态规划题目讲解】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

相关文章

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

动态规划---打家劫舍

题目: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 思路: 动态规划五部曲: 1.确定dp数组及含义 dp数组是一维数组,dp[i]代表

软考系统规划与管理师考试证书含金量高吗?

2024年软考系统规划与管理师考试报名时间节点: 报名时间:2024年上半年软考将于3月中旬陆续开始报名 考试时间:上半年5月25日到28日,下半年11月9日到12日 分数线:所有科目成绩均须达到45分以上(包括45分)方可通过考试 成绩查询:可在“中国计算机技术职业资格网”上查询软考成绩 出成绩时间:预计在11月左右 证书领取时间:一般在考试成绩公布后3~4个月,各地领取时间有所不同

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

题目1254:N皇后问题

题目1254:N皇后问题 时间限制:1 秒 内存限制:128 兆 特殊判题:否 题目描述: N皇后问题,即在N*N的方格棋盘内放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在同一斜线上。因为皇后可以直走,横走和斜走如下图)。 你的任务是,对于给定的N,求出有多少种合法的放置方法。输出N皇后问题所有不同的摆放情况个数。 输入

题目1380:lucky number

题目1380:lucky number 时间限制:3 秒 内存限制:3 兆 特殊判题:否 提交:2839 解决:300 题目描述: 每个人有自己的lucky number,小A也一样。不过他的lucky number定义不一样。他认为一个序列中某些数出现的次数为n的话,都是他的lucky number。但是,现在这个序列很大,他无法快速找到所有lucky number。既然

数学建模笔记—— 非线性规划

数学建模笔记—— 非线性规划 非线性规划1. 模型原理1.1 非线性规划的标准型1.2 非线性规划求解的Matlab函数 2. 典型例题3. matlab代码求解3.1 例1 一个简单示例3.2 例2 选址问题1. 第一问 线性规划2. 第二问 非线性规划 非线性规划 非线性规划是一种求解目标函数或约束条件中有一个或几个非线性函数的最优化问题的方法。运筹学的一个重要分支。2

轨迹规划-B样条

B样条究竟是干啥的?白话就是给出一堆点,用样条的方式,给这些点连接起来,并保证丝滑的。 同时B样条分为准均匀和非均匀,以下为准均匀为例。 参考链接1:https://zhuanlan.zhihu.com/p/50626506https://zhuanlan.zhihu.com/p/50626506 参考链接2: https://zhuanlan.zhihu.com/p/536470972h