首页 > 其他分享 >G. Paint Charges

G. Paint Charges

时间:2024-02-09 19:22:07浏览次数:30  
标签:涂色 Charges cells 位置 Paint charge th xrightarrow

G. Paint Charges

A horizontal grid strip of $n$ cells is given. In the $i$-th cell, there is a paint charge of size $a_i$. This charge can be:

  • either used to the left — then all cells to the left at a distance less than $a_i$ (from $\max(i - a_i + 1, 1)$ to $i$ inclusive) will be painted,
  • or used to the right — then all cells to the right at a distance less than $a_i$ (from $i$ to $\min(i + a_i - 1, n)$ inclusive) will be painted,
  • or not used at all.

Note that a charge can be used no more than once (that is, it cannot be used simultaneously to the left and to the right). It is allowed for a cell to be painted more than once.

What is the minimum number of times a charge needs to be used to paint all the cells of the strip?

Input

The first line of the input contains an integer $t$ ($1 \le t \le 100$) — the number of test cases in the test. This is followed by descriptions of $t$ test cases.

Each test case is specified by two lines. The first one contains an integer $n$ ($1 \le n \le 100$) — the number of cells in the strip. The second line contains $n$ positive integers $a_1, a_2, \dots, a_n$ ($1 \le a_i \le n$), where $a_i$ is the size of the paint charge in the $i$-th cell from the left of the strip.

It is guaranteed that the sum of the values of $n$ in the test does not exceed $1000$.

Output

For each test case, output the minimum number of times the charges need to be used to paint all the cells of the strip.

Example

input

13
1
1
2
1 1
2
2 1
2
1 2
2
2 2
3
1 1 1
3
3 1 2
3
1 3 1
7
1 2 3 1 2 4 2
7
2 1 1 1 2 3 1
10
2 2 5 1 6 1 8 2 8 2
6
2 1 2 1 1 2
6
1 1 4 1 3 2

output

1
2
1
1
1
3
1
2
3
4
2
3
3

Note

In the third test case of the example, it is sufficient to use the charge from the $1$-st cell to the right, then it will cover both cells $1$ and $2$.

In the ninth test case of the example, you need to:

  • use the charge from the $3$-rd cell to the left, covering cells from the $1$-st to the $3$-rd;
  • use the charge from the $5$-th cell to the left, covering cells from the $4$-th to the $5$-th;
  • use the charge from the $7$-th cell to the left, covering cells from the $6$-th to the $7$-th.

In the eleventh test case of the example, you need to:

  • use the charge from the $5$-th cell to the right, covering cells from the $5$-th to the $10$-th;
  • use the charge from the $7$-th cell to the left, covering cells from the $1$-st to the $7$-th.

 

解题思路

  官方题解给出的 dp 状态定义不好直接想到,这里先给出容易想到但有问题的做法,然后再引出官方题解的做法。

  定义 $f(i,j)$ 表示所有由前 $i$ 个位置将前缀 $1 \sim j$ 都涂上色的方案中操作次数的最小值。根据对第 $i+1$ 个位置执行的操作将 $f(i,j)$ 转移到 $i+1$ 对应的状态。

  • 如果第 $i+1$ 个位置不执行操作,那么显然有 $f(i,j) \xrightarrow{0} f(i+1, j)$。
  • 如果第 $i+1$ 个位置执行向左涂色的操作,只有当 $j \geq i+1-a_{i+1}$,有 $f(i,j) \xrightarrow{1} f(i+1, \max\{{i+1,j}\})$。
  • 如果第 $i+1$ 个位置执行向右涂色的操作,只有当 $j \geq i$,有 $f(i,j) \xrightarrow{1} f(i+1, \max\{{i+a_{i+1},j}\})$。

  最后的答案就是 $f(n,n)$。如果你按照这个做法来做那么就会发现题目倒数第 $3$ 个样例跑出的答案是 $3$,实际上应该选择第 $5$ 个位置向右涂色,第 $7$ 个位置向左涂色。由于状态的定义要保证前缀被涂色,因此枚举到 $i+1=5$ 时,位置 $1 \sim 4$ 没被涂色而从位置 $5$ 向右涂色这种状态是不存在的。

  因此可以知道在枚举 $i$ 的过程中不一定要保证前缀被涂色,同时被涂色的区间不一定只有连续的一段。对于这样的状态,就可以引出官方题解中给出的状态定义,即只关心此时最靠左没被涂色的位置,和最靠右已被涂色的位置。

  定义 $f(i,j,k)$ 表示所有由前 $i$ 个位置使得最靠左没被涂色的位置为 $j$,最靠右已涂色的位置为 $k$ 的方案中操作次数的最小值。状态转移方程为:

  • 如果第 $i+1$ 个位置不执行操作,那么显然有 $f(i,j.k) \xrightarrow{0} f(i+1, j, k)$。
  • 如果第 $i+1$ 个位置执行向左涂色的操作,分两种情况。如果 $j < i+1-a_{i+1}-1$,则涂色后最靠左没被涂色的位置还是 $j$,最靠右被涂色的位置取决于 $k$ 和 $i+1$。因此有 $f(i,j,k) \xrightarrow{1} f(i+1, j, \max\{{k,i+1}\})$。否则如果 $j \geq i+1-a_{i+1}-1$,继续分两种情况:$k < i+1$,显然涂色后最靠左没被涂色的位置为 $i+2$,最靠右已涂色的位置为 $i+1$,因此有 $f(i,j,k) \xrightarrow{1} f(i+1, i+2, i+1)$。$k \geq i+1$,由于是通过前 $i$ 个位置使得第 $k$ 个位置被涂色,因此区间 $[i, k]$ 一定都被涂色,所以涂色后最靠左没被涂色的位置为 $k+1$,最靠右已涂色的位置为 $k$,有 $f(i,j,k) \xrightarrow{1} f(i+1, k+1, k)$。两种情况综合一下就有 $f(i,j,k) \xrightarrow{1} f(i+1, \max\{{k,i+1}\}+1, \max\{{k,i+1}\})$。
  • 如果第 $i+1$ 个位置执行向右涂色的操作,同理分两种情况。如果 $j < i+1$,则有 $f(i,j,k) \xrightarrow{1} f(i+1,j, \max\{{k, i+a_{i+1}}\})$。否则如果 $j \geq i+1$,则有 $f(i,j,k) \xrightarrow{1} f(i+1, \max\{{k, i+a_{i+1}}\}+1, \max\{{k, i+a_{i+1}}\})$。

  AC 代码如下,时间复杂度为 $O(n^3)$:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 110;

int a[N];
int f[N][N][N];

void solve() {
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", a + i);
    }
    memset(f, 0x3f, sizeof(f));
    f[0][1][0] = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 1; j <= n + 1; j++) {
            for (int k = 0; k <= n; k++) {
                f[i + 1][j][k] = min(f[i + 1][j][k], f[i][j][k]);
                if (j < i + 1 - a[i + 1] + 1) {
                    int &v = f[i + 1][j][max(k, i + 1)];
                    v = min(v, f[i][j][k] + 1);
                }
                else {
                    int &v = f[i + 1][max(k, i + 1) + 1][max(k, i + 1)];
                    v = min(v, f[i][j][k] + 1);
                }
                if (j < i + 1) {
                    int &v = f[i + 1][j][min(n, max(k, i + a[i + 1]))];
                    v = min(v, f[i][j][k] + 1);
                }
                else {
                    int &v = f[i + 1][min(n, max(k, i + a[i + 1])) + 1][min(n, max(k, i + a[i + 1]))];
                    v = min(v, f[i][j][k] + 1);
                }
            }
        }
    }
    printf("%d\n", f[n][n + 1][n]);
}

int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        solve();
    }
    
    return 0;
}

 

参考资料

  Codeforces Round 923 (Div. 3) Editorial:https://codeforces.com/blog/entry/125597

  Codeforces Round 923 (Div. 3) A-G:https://zhuanlan.zhihu.com/p/681725397

  Codeforces Round 923 (Div. 3) A - G:https://zhuanlan.zhihu.com/p/681721421

标签:涂色,Charges,cells,位置,Paint,charge,th,xrightarrow
From: https://www.cnblogs.com/onlyblues/p/18012597

相关文章

  • CodeForces 1927G Paint Charges
    洛谷传送门CF传送门看到\(n\le100\)考虑\(O(\text{poly}(n))\)dp。发现从左向右决策,因为一个点可以向左或向右覆盖,所以需要记最靠左的未覆盖的位置\(j\)和最靠右的已覆盖位置\(k\),状态就是\(f_{i,j,k}\),dp最小的覆盖次数。转移的讨论很简单。考虑不覆盖还是向左......
  • CF1764H Doremy's Paint 2 题解
    题目链接:CF或者洛谷高分题,感觉挺有意思的题,值得一提的是这个题的\(1\)和\(3\)版本却是两个基础题。一开始以为跟这道差不多:P8512[YnoiEasyRound2021]TEST_152题解。后面重新读了一下发现一个有趣的点:也就是是说操作的\(val\)并不太好搞了,如果\(val\)确定就基......
  • MFC OnPaint 绘制一行简单文字
    ▲绘制一行简单文字OnPaint()消息。voidCMFCApplication6Dlg::OnPaint(){CPaintDCcdc(this);/***OnPaint绘制简单文字*****/cdc.TextOutW(100,100,TEXT("你好,MFC!")); if(IsIconic()) { CPaintDCdc(this);//用于绘制的设备上下文 SendMessa......
  • CF1764H Doremy's Paint 2 题解
    题目链接先断环成链,由于对于多组询问不好一起处理,我们先考虑单组询问的处理方式。一个很暴力的想法是每次模拟题目要求的操作并且最后数颜色,我们这是在通过下标进行操作最后再数颜色,而很多对于下标的操作都是不必要的,考虑直接枚举颜色进行判定。对于每种颜色,它对于最后答案有贡......
  • 14、绘制图形(QPainter)
    效果 //定义一个新的类#ifndefPAINTERAREA_H#definePAINTERAREA_H#include<QObject>#include<QWidget>//QPen画笔是基本的图形对象,绘制直线、曲线、多边形等形状#include<QPen>//QBrush画刷是基本的图形对象,主要用于填充,比如矩形、多边形等形状#include<Q......
  • 在线P图工具(基于minipaint开发)
    在浏览github过程中,发现一个超级实用的仓库,viliulsle开发的minipaint,类似于photoshop的网页版。基于webpack开发的,打包非常简单,故自己搭建了一套。在线预览在线ps网页版源码地址https://github.com/viliusle/miniPaint功能介绍文件:打开图像,目录,URL,数据URL,拖放,保存(PNG,JPG,B......
  • 使用QPainter制作一个简易的相册
    PlayImage记得一键三连哦一个使用简单的QPainter绘图事件实现图片播放器的简易demo支持图片切换支持多路更新,自己扩展即可支持幻灯片播放PlayImage自定义控件支持复用,对外提供updateImage和updatePixmap接口,对传入的image和pixmap进行图片更新PlayImage控件支持多线程调......
  • 什么是 Web 应用性能参数中的 First Contentful Paint
    "FirstContentfulPaint"(简称FCP)是一个非常重要的性能指标,用于测量我们的网页在用户的设备上渲染出第一片有意义内容的时间点。这个指标是Web性能用户体验的关键部分,因为它直接关系到用户对网站加载速度的第一印象。在互联网世界中,每一毫秒的延迟都可能影响用户的满意度,甚至影......
  • 浏览器关于 Largest Contentful Paint (LCP) 的计算机制
    LargestContentfulPaint(LCP)是一种用户体验的性能指标,旨在帮助开发者了解用户在浏览网页时视觉渲染的速度。LCP主要衡量的是视觉上最大的页面元素何时出现在屏幕上,这包括图像元素、视频元素或者包含文本的元素(如段落或列表项)。如果LCP时间较长,用户可能会感觉到页面加载速......
  • 什么是前端应用开发的 LCP(Largest Contentful Paint) 指标
    在网页性能优化的领域里,LCP(LargestContentfulPaint,最大内容绘制)是一个非常重要的性能指标。它测量的是从页面开始加载到页面的"主要内容"完全呈现在屏幕上所需的时间。换句话说,LCP是测量用户何时看到页面的"主要内容"的指标。在理解LCP之前,我们需要知道一个概念,那就是......