首页 > 其他分享 >[题解]CF1312E Array Shrinking

[题解]CF1312E Array Shrinking

时间:2024-06-24 12:34:38浏览次数:3  
标签:int 题解 合并 区间 CF1312E Array dp

思路

本题为 P3146 变式,也算是一道很经典的区间 DP 题了。

因为 \(n \leq 500\),考虑区间 DP。定义 \(dp_{i,j}\) 表示操作 \([i,j]\) 区间剩余长度的最小值。

那么,我们可以枚举一个中间值 \(k\),可以显然地得到一个状态转移方程(即不能合二为一的情况):

\[ dp_{i,j} = \min(dp_{i,k} + dp_{k + 1,j}) \]

然后,我们再来考虑两个区间能够合并的情况。

如果 \([i,k]\) 和 \([k + 1,j]\) 能合并,当且仅当 \(dp_{i,k} = dp_{k + 1,j} = 1\),以及两段区间合并出的值相同。

但是,我们现在并不知道两段区间的值具体是多少。所以,现在有两种处理方式:

  1. 将合并区间得到的值作为 \(dp\) 的一维用来枚举,但这显然是不行的,因为时间复杂度将变为 \(\Theta(n^3m)\)。(其中 \(m = \max\{a_i\}\)。)
  2. 再开一个数组 \(f\) 记录两个区间的合并后的值。

那么,对于这个问题显然只能选择第二种方案。

由此,不妨令 \(f_{i,j}\) 表示合并 \([i,j]\) 区间得到的数值。那么,我们就可以在处理 \(dp_{i,j}\) 的时候同时更新 \(f_{i,j}\)。

综上,对于 \([i,k]\) 和 \([k + 1,j]\) 能合并,需满足:

\[ dp_{i,k} = dp_{k + 1,j} = 1 \wedge f_{i,k} = f_{k + 1,j} \]

时间复杂度:\(\Theta(n^3)\)。

Code

#include <bits/stdc++.h>  
#define re register  
  
using namespace std;  
  
const int N = 510,inf = 0x3f3f3f3f;  
int n,ans = inf;  
int arr[N];  
int f[N][N],dp[N][N];  
  
inline int read(){  
    int r = 0,w = 1;  
    char c = getchar();  
    while (c < '0' || c > '9'){  
        if (c == '-') w = -1;  
        c = getchar();  
    }  
    while (c >= '0' && c <= '9'){  
        r = (r << 3) + (r << 1) + (c ^ 48);  
        c = getchar();  
    }  
    return r * w;  
}  
  
int main(){  
    memset(dp,inf,sizeof(dp));  
    n = read();  
    for (re int i = 1;i <= n;i++) arr[i] = read();  
    for (re int i = 1;i <= n;i++){  
        f[i][i] = arr[i];  
        dp[i][i] = 1;  
    }  
    for (re int l = 1;l <= n;l++){  
        for (re int i = 1;i + l - 1 <= n;i++){  
            int j = i + l - 1;  
            for (re int k = i;k < j;k++){  
                dp[i][j] = min(dp[i][j],dp[i][k] + dp[k + 1][j]);//不合并   
                if (dp[i][k] == dp[k + 1][j] && dp[i][k] == 1 && f[i][k] == f[k + 1][j]){//满足条件,说明两区间可以合并   
                    dp[i][j] = min(dp[i][j],dp[i][k]);//更新两个 DP 数值   
                    f[i][j] = f[i][k] + 1;  
                }  
            }  
        }  
    }  
    printf("%d",dp[1][n]);  
    return 0;  
}  

标签:int,题解,合并,区间,CF1312E,Array,dp
From: https://www.cnblogs.com/WaterSun/p/18264794

相关文章

  • [题解]CF1223F Stack Exterminable Arrays
    CCF出的原题观摩一下。思路首先可以用一个Trie来维护。在这里对本文中的一些变量做一下说明。\(p\)表示当前维护的Trie中,指向的元素编号。\(t_i\)表示在Trie中编号为\(i\)的元素在原序列中的值。\(f_i\)表示在Trie中编号为\(i\)的元素在Trie中的父节点。......
  • [题解]CF1175E Minimal Segment Cover
    思路这是一道简单的DP题,DP题的核心就是状态转移。先来说一说\(dp\)数组的含义。\(dp_{i,j}\)表示从\(i\)这个点用\(2^j\)条线段能走到的最远的点。我们再来考虑一下边界情况。因为我们只用\(2^0\)条线段,那么:\(dp_{i,0}=\max(dp_{i,0},r)\)接着,我们递推一......
  • [题解]CF1092D1 Great Vova Wall (Version 1)
    思路发现,如果相邻元素的奇偶性相同,那么一定能通过在较低的位置竖着放若干个如果在\(i\)的位置竖着放一块砖头,使得这两列的高度相同。那么,我们想到直接考虑\(h_i\)的奇偶性,即将\(h_i\leftarrowh_i\bmod2\)。如果\(h_i=h_{i+1}\),我们显然可以同时使\(h_i\)和\(h......
  • [题解]CF1070C Cloud Computing
    思路考虑用线段树维护区间信息:价格在\([l,r]\)之间的CPU的数量。购买所有价格在\([l,r]\)之间CPU所需的钱。容易将区间修改转化为差分,从而实现单点修改。于是可以使用\(n\)个vector存储第\(i\)天所需进行的修改。查询第\(i\)天的答案时,如果不足\(k\)......
  • [题解]CF1746B Rebellion
    思路首先我们需要看到题目一个特殊的地方:这个序列中只存在\(0\)和\(1\)。那么,我们不难发现最终的答案一定是形如下面的序列:\(0,\dots,0,1,\dots,1\)。知道了这些,就很好想了。我们从后往前枚举,如果当前一位为\(0\)了,就从\(last\simi\)扫一遍,如果有\(1\)将最靠前的\(......
  • [题解]CF1742G Orray
    思路做这道题之前,首先要知道一个性质:\(a\operatorname{or}b\geqa\)。那么,我们就能得出一个结论:经过一定顺序的排列,最多经过\(\lceil\log_2^{a_{\max}}\rceil\)个数就能让前缀或的值达到最大值。我们不妨令有一个位置\(i\),\(b_1,b_2,\dots,b_{i-1}\)单调递增,而\(b_i......
  • [题解]CF1742E Scuza
    2022/11/23:修改了一下代码。题意有\(T\)组数据,每次给出一个\(n,q\),表示台阶的数量和询问的次数。然后再给出一个\(a_i\)为台阶高度的差分数组。每次询问给出一个\(k\),表示每次能走\(k\)个单位的高度。问:最高能到达的高度。思路考虑暴力,我们知道了高度的差分数组,那......
  • [题解]CF1741D Masha and a Beautiful Tree
    思路我们可以观察样例,不难发现:对于任意一段长度为\(2^k\)的区间中,如果最大值减最小值加\(1\)等于此区间的长度,那么一定有解。因为,我们的目标是使整个序列升序排列。因此,我们在一个区间内的最大值减最小值加\(1\)与区间长度是相等的。所以,我们可以用上述结论为判断无解的......
  • [题解]CF1741B Funny Permutation
    思路简单构造题,我们可以分为三种情况进行构造。\(n=3\)时,一定无解,输出-1。(你可以试试)\(n\bmod2=1\wedgen\neq3\)时,我们直接先输出\(n,n-1\),然后顺序输出即可。证明:令\(a\)为最后构造出的序列。那么,\(a_1=n,a_2=n-1,a_i=i-2(3\leqi\leq......
  • [题解]CF1732C2 Sheikh (Hard Version)
    思路首先证明一下当序列扩大时答案一定不劣。考虑\(f(l,r)\)到\(f(l,r+1)\)的变化。\[\begin{aligned}f(l,r)-f(l,r+1)&=s_{l,r}-xs_{l,r}-s_{l,r+1}+xs_{l,r+1}\\&=xs_{l,r+1}-xs_{l,r}-a_{r+1}\\&......