首页 > 其他分享 >题解 CF1849D

题解 CF1849D

时间:2024-02-05 22:33:38浏览次数:24  
标签:begin 涂过 end min 题解 small CF1849D cases

萌新的第一篇题解

题目大意

对于一个初始颜色都为蓝色的数组 \(a_1,a_2,\dots,a_n\) 其中 \(a_n \in \{0,1,2\}\),现在可以进行两个操作:

  1. 花费 \(1\) 个金币,将 \(a_i\) 涂成红色;
  2. 选择一个红色的 \(a_i > 0\),将 \(a_{i-1}\) 或 \(a_{i+1}\) 涂成红色,同时 \(a_i\) 减 \(1\)。

输出金币的最小数目。

动态规划

由于操作二只能对其左右的格子产生影响,故而我们考虑动态规划,将其转换为一个 \(01\) 背包问题。同时,我们还需要维护格子的数字 \(a_i\),故而设计一个三维数组。

\[d[i][j][k] \ \ \ \ (j\in \{0,1\}, \ k \in \{0, 1, 2\}且k \leqslant a_i) \]

转移到 \(d[a_i]\) 时,\(a_i\) 之前的都被涂过。

当 \(j = 0\) 时说明 \(a_i\) 暂时还未被涂过,\(j = 1\) 时说明 \(a_i\) 已经被涂过了。

\(k = a_i\) 说明 \(a_i\) 没有通过操作二涂他左侧的那格,此时只能从 \(d[a_{i-1}][1]\) 转移过来;\(k = a_i - 1\) 说明 \(a_i\) 涂了他左边的那格,此时只能从 \(d[a_{i-1}][0]\) 转移过来。

\[\begin{aligned}d[i][1][a_i]&=\min \begin{cases} d[i-1][1][a_{i-1}] + 1&(a_{i-1}=0)\ \ \ \small{直接涂a_i格,耗费一金币}\\ d[i-1][1][a_{i-1}]&(a_{i-1}>0) \ \ \ \small{让没涂过 a_{i-2} 的 a_{i-1}涂a_i}\\ d[i-1][1][a_{i-1}-1]&(a_{i-1}>1) \ \ \ \small{让涂过 a_{i-2} 的 a_{i-1}涂a_i} \end{cases}\\ d[i][1][a_i - 1]&=\min \begin{cases} d[i-1][0][a_{i-1}] + 1&(a_i>0,a_{i-1}=0)\ \ \ \small{直接涂a_i格,耗费一金币,同时让a_i涂a_{i-1}}\\ d[i-1][0][a_{i-1} - 1] + 1&(a_i>0,a_{i-1}>0)\ \ \ \small{同理,但这里是涂过a_{i-2}的a_{i-1}} \end{cases}\\ d[i][0][a_i]&=\min \begin{cases} d[i-1][1][a_{i-1}]&\ \ \ \small{不涂a_i格,a_{i-1} 没涂 a_{i-2}}\\ d[i-1][1][a_{i-1}-1]&(a_{i-1}>0)\ \ \ \small{不涂a_i格,a_{i-1} 涂过 a_{i-2}} \end{cases}\\ d[i][0][a_i-1]&=\min \begin{cases} d[i-1][0][a_{i-1}]&(a_i>0,a_{i-1}=0)\ \ \ \small{不涂a_i格,之后让a_i 涂 a_{i-1}}\\ d[i-1][0][a_{i-1}-1]&(a_i>0,a_{i-1}>0)\ \ \ \small{同理,但这里涂过 a_{i-2} 的 a_{i-1}} \end{cases}\end{aligned}\]

进行初始化

\[\begin{aligned} a_0 &= 0,\\ d[0][1][0] &= 0,\\ d[0][0][0] &= INF \end{aligned} \]

由于最后一格 \(a_n\) 必须要被涂,故

\[ans=\min \begin{cases} d[n][1][a_{n}]&(a_{n}=0)\\ d[n][1][a_{n} - 1]&(a_{n}>0) \\ \end{cases}\\ \]

代码

#include<bits/stdc++.h>
using namespace std;
#define fr(a, b, i) for (int i = a; i <= b; i++)
#define Fr(a, b, i) for (int i = a; i < b; i++)
#define rf(a, b, i) for (int i = a; i >= b; i--)
#define rF(a, b, i) for (int i = a; i > b; i--)

int n, a[200010], d[200010][2][3];
int main()
{
    cin >> n;
    fr(1, n, i) cin >> a[i];
    d[0][1][0] = 0;
    d[0][0][0] = 9999999;
    fr(1, n, i){
        d[i][1][a[i]] = d[i - 1][1][a[i - 1]] + 1; 
        if(a[i - 1] > 0) 
            d[i][1][a[i]] = min(d[i - 1][1][a[i - 1]], d[i][1][a[i]]);
        if(a[i - 1] > 1) 
            d[i][1][a[i]] = min(d[i - 1][1][a[i - 1] - 1], d[i][1][a[i]]);
        
        if(a[i] > 0) {
            d[i][1][a[i] - 1] = d[i - 1][0][a[i - 1]] + 1;
            if(a[i - 1] > 0) 
                d[i][1][a[i] - 1] = min(d[i - 1][0][a[i - 1] - 1] + 1, d[i][1][a[i] - 1]);
        }
        
        d[i][0][a[i]] = d[i - 1][1][a[i - 1]];
        if(a[i - 1] > 0)    
            d[i][0][a[i]] = min(d[i - 1][1][a[i - 1] - 1], d[i][1][a[i]]);
        
        if(a[i] > 0){
            d[i][0][a[i] - 1] = d[i - 1][0][a[i - 1]];
            if(a[i - 1] > 0) 
                d[i][0][a[i] - 1] = min(d[i][0][a[i] - 1], d[i - 1][0][a[i - 1] - 1]);
        }

    }
    cout << min(d[n][1][a[n]], (a[n] > 0) ? d[n][1][a[n] - 1] : 999999);
    return 0;
}

标签:begin,涂过,end,min,题解,small,CF1849D,cases
From: https://www.cnblogs.com/anjack511/p/18008941/solution-CF1849-D

相关文章

  • F. 乘积最大(题解)
    题目今年是国际数学联盟确定的“2000——世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰90周年。在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友XZ也有幸得以参加。活动中,主持人给所有参加活动的选手出了这样一道题目:设有一个长度为......
  • [ARC135D] Add to Square 题解
    题目链接点击打开链接题目解法很牛的题!!!先考虑一步很牛的转化:把矩阵黑白染色,且\(i+j\)为奇数的位置的值取反,每次操作变为左上右下\(+v\),左下右上\(-v\)这样有啥好处?操作不会使行和列的和改变考虑答案的下界显然是:\(\max\{\)行的绝对值之和,列的绝对值之和\(\}\)这里给出......
  • luogu2647题解
    首先这道题没有规定选几个。一开始我以为是全选,然后想了个贪心才发现看错了。那我们先来假设选\(m\)个。这个题的每个物品都会影响后面物品的收益,不好看。由于每个物品\(i\)对后选的其他物品减少的收益都是\(R_i\),因此我们在保证总价值不变的情况下转化一下,把该物品的价......
  • P10125 「Daily OI Round 3」Simple 题解
    题目传送门简单模拟,主要考察字符串。首先输入一个char类型的数组,然后直接遍历每一位是否为Acoipp或Svpoll即可。//Simple//codeby:cq_irritater//time:2024/02/04#include<bits/stdc++.h>usingnamespacestd;chara[10];intmain(){//freopen("c......
  • 中文数字的应用及其问题解决之道
    中文数字,也称汉字数字,是中文语言中表示数字的一种方式。它们不仅有着悠久的历史和文化背景,还在日常生活中发挥着重要的作用。本文将探讨中文数字的应用领域,并介绍它们如何解决实际问题。中文数字-阿拉伯数字转换|一个覆盖广泛主题工具的高效在线平台(amd794.com)https:/......
  • P2367 语文成绩 题解
    语文成绩题目背景语文考试结束了,成绩还是一如既往地有问题。题目描述语文老师总是写错成绩,所以当她修改成绩的时候,总是累得不行。她总是要一遍遍地给某些同学增加分数,又要注意最低分是多少。你能帮帮她吗?输入格式第一行有两个整数\(n\),\(p\),代表学生数与增加分数的次数。......
  • 题解 ARC171D【Rolling Hash】
    来补题了。昨天赛时想法是对的,代码写错了,没调过太可惜了。显然\(P>n\)时必定有解。设前缀\([1,i]\)的哈希值为\(s_i\),显然\([l,r]\)的哈希值不为\(0\)的充要条件是\(s_{l-1}\nes_r\)。建立一个点的编号为\(0\simn\)的图,对于每个输入的区间\([l,r]\),连接一条边......
  • 【洛谷 P2437】蜜蜂路线 题解(递归+记忆化搜索+高精度)
    蜜蜂路线题目描述一只蜜蜂在下图所示的数字蜂房上爬动,已知它只能从标号小的蜂房爬到标号大的相邻蜂房,现在问你:蜜蜂从蜂房开始爬到蜂房,,有多少种爬行路线?(备注:题面有误,右上角应为)输入格式输入的值输出格式爬行有多少种路线样例#1样例输入#1114样例输出#1377提示对于100%的......
  • 题解 ARC171C【Swap on Tree】
    每棵子树内只可能有至多一个外来的数,且外来的数是多少并不影响方案数,因此考虑设\(f_{u,i,0/1}\)表示考虑以\(u\)为根的子树,与\(u\)相连的所有边中断了\(i\)条,且\(u\)与其父亲之间的边有没有断的方案数。设\(g_{u,c}=\sumf_{u,i,c}\)。每个节点的初始状态是\(f_{u,0,......
  • 题解 ARC171B【Chmax】
    考察题面中的操作究竟做了什么,不难发现其实是将所有满足\(P_i>i\)的\(i\toP_i\)连边,得到若干条链,然后\(B_i\)即为\(i\)所在链的最后一个节点。显然,存在\(A_i<i\)时无解,存在\(A_i\nei\)但\(A_j=i\)时也无解。否则,每个\(A_i\nei\)的位置填的数都唯一确定......