首页 > 其他分享 >CF1987F Interesting Problem

CF1987F Interesting Problem

时间:2024-10-14 12:43:28浏览次数:1  
标签:int Interesting rep 区间 Problem CF1987F 转移 dp define

前两个月被这题薄纱了,最后特判了几个数据通过,现在来补。

先看简单版本,注意到后面的删除不会影响到前面的,而如果前面删除了 \(x\) 次,那么对于后面的任意一点 \(i\),只要是满足 \(i-2x\le a_i\le i\) 这个条件就可以删除。

结合数据范围容易想到设 \(f_{l,r,x}\) 表示对于 \([l,r]\) 这个区间内,前面删除了 \(x\) 次,能删除最多的次数。

这个 dp 有两个转移,一个是 \(f_{l,r,x}\leftarrow f_{l+1,r-1,x}\),它的前提是在 \([l+1,r-1]\) 的区间中能够删完且 \(l\) 这个位置可以删,一个是 \(f_{l,r,x}\leftarrow f_{l,k,x}+f_{k+1,r,x+f_{l,k,x}}\),然后对于前缀取最大值即可。

这样子可以做到 \(\mathcal{O}(n^4)\),可以通过简单版本。

考虑优化。发现这样子的区间 dp 直接优化是优化不了的,考虑优化状态。观察它的转移,发现本质上第一个转移是考虑能不能将区间 \([l,r]\) 中的数删完,而第二个转移则是合并能删完与不能删的区间。这启发我们改变状态,设 \(f_{l,r}\) 表示在区间 \([l,r]\) 前面至少要删多少数才能使得该区间删完所有数,转移是与刚刚那个 dp 转移类似的,而这个 dp 只需要 \(\mathcal{O}(n^3)\) 完成,最后使用一个 \(g_i\) 表示对于一个前缀 \([1,i]\) 最多删多少数,利用 \(f\) 简单转移即可。

总时间复杂度 \(\mathcal{O}(n^3)\),可以通过困难版本。

代码:

#include <bits/stdc++.h>
#define rep(i, l, r) for (int i = l; i <= r; ++ i)
#define rrp(i, l, r) for (int i = r; i >= l; -- i)
#define pii pair <int, int>
#define eb emplace_back
#define id(x, y) n * (x - 1) + y
#define ls p << 1
#define rs ls | 1
using namespace std;
constexpr int N = 800 + 5, M = (1ll << 31) - 1, P = 998244353;
constexpr double PI = acos (-1.0);
inline int rd () {
  int x = 0, f = 1;
  char ch = getchar ();
  while (! isdigit (ch)) {
    if (ch == '-') f = -1;
    ch = getchar ();
  }
  while (isdigit (ch)) {
    x = (x << 1) + (x << 3) + ch - 48;
    ch = getchar ();
  }
  return x * f;
}
int qpow (int x, int y) {
  int ret = 1;
  for (; y; y >>= 1, x = x * x % P) if (y & 1) ret = ret * x % P;
  return ret;
}
int f[N][N], g[N];
int n;
int a[N];
signed main () {
  for (int T = rd (); T; -- T) {
    n = rd ();
    rep (i, 1, n) a[i] = rd ();
    rep (i, 1, n) rep (j, 1, n) f[i][j] = 1e9, g[i] = 0;
    rep (i, 1, n - 1) {
      if (a[i] <= i && (i - a[i]) % 2 == 0) f[i][i + 1] = (i - a[i]) / 2;
    }
    rep (len, 3, n) {
      rep (l, 1, n - len + 1) {
        int r = l + len - 1;
        if (a[l] <= l && (l - a[l]) % 2 == 0) {
          int must = (l - a[l]) / 2;
          if (f[l + 1][r - 1] <= must) f[l][r] = must;
        } 
        rep (k, l, r - 1) {
          if (((k - l + 1) & 1) || ((r - k) & 1)) continue;
          f[l][r] = min (f[l][r], max (f[l][k], f[k + 1][r] - (k - l + 1) / 2));
        }
      }
    }
    rep (i, 1, n) {
      g[i] = g[i - 1];
      rep (j, 1, i - 1) {
        if (f[j][i] <= g[j - 1]) g[i] = max (g[i], g[j - 1] + (i - j + 1) / 2);
      }
    }
    printf ("%d\n", g[n]);
  }
}

标签:int,Interesting,rep,区间,Problem,CF1987F,转移,dp,define
From: https://www.cnblogs.com/lalaouyehome/p/18463862

相关文章

  • PyTorchStepByStep - Chapter 3: A Simple Classification Problem
     X,y=make_moons(n_samples=100,noise=.3,random_state=0)X_train,X_val,y_train,y_val=train_test_split(X,y,test_size=.2,random_state=13) sc=StandardScaler()sc.fit(X_train)X_train=sc.transform(X_train)X_val=sc.transform(X_val......
  • P11022 「LAOI-6」Yet Another Graph Coloration Problem
    P11022「LAOI-6」YetAnotherGraphColorationProblem-洛谷|计算机科学教育新生态(luogu.com.cn)关于无解情况,如果这个图有两块连通块,那么不可能同时有黑色白色,假设\(1,2\)连通块,设\(1\)中有黑色,因为\(2\)中点不能到\(1\),所以\(2\)中只能是黑色,又因为\(2\)中......
  • Small Permutation Problem (Easy Version)
    算法考虑转化每个点\(p_i\)在一个平面直角坐标系中表示为点\((i,p_i)\)于是转化为一个棋盘问题,即每一个点不能在同一行/同一列\(a\)数组的限制相当于在左下角为\((0,0)\),右上角为\((i,i)\)中的正方形中,有\(a_i\)个棋子于是在每一次加入的时候,都只能在......
  • Problem Set 1 Installing MikTex
    ProblemSet1XXXDue:10/10/2024IntroductionThisdocumentwasproducedbyRusingRMarkdown.Tocompletethisweeksassignment,wewillaskyoutocompleteaseriesofanalyticalandcodingexercises.TheAnalyticalExercisesrequirenocoding,whereasth......
  • PAT甲级-1150 Travelling Salesman Problem
    题目 题目大意旅行商问题是NP-hard问题,即没有多项式时间内的解法,但是可以验证答案是否正确。给定一个无向图,判断简单环,复杂环和非环。对应“TSsimplecycle”、“TScycle”、“NotaTScycle”。还要求出环的最小路径权值和,及对应的索引。思路主要思路在于如何区分简......
  • 分布式理论-拜占庭将军问题(The Byzantine Generals Problem)
    文章目录模拟拜占庭问题苏秦的困境两忠一判难题口信消息型拜占庭问题之解两轮方案原则两轮方案实现签名消息型拜占庭问题之解苏秦问题和分布式的关系分布式环境下常见容错算法有哪些本文借助战国苏秦合纵六国灭秦国的故事探讨拜占庭将军问题,充分展示拜占庭将军问题......
  • abc371E I Hate Sigma Problems
    给定长度为N的数组A[i],记f(l,r)表示区间[l,r]内不同A[i]的个数,求所有子区间f(i,j)之和。1<=N<=2E5,1<=A[i]<=N分析:贡献法,为了方便统计,区间中重复的数字以最左边出现的数为准,保证不重不漏。对于A[i],假设其上一次出现的位置为p,那么包含该数字的左端点可以是p+1,p+2,...,i,右端点可......
  • Skills - 2022 International Collegiate Programming Contest, Jinan Site, Problem
    有3种技能,\(n(\le10^3)\)天内每天可以对一个技能进行学习,第i天学习第j个技能可以为第j个技能增加\(a_{i,j}(\le10^4)\)的熟练度。在第i天结束时,每个技能的熟练度会减去距离上次学习该技能的天数,但最多减到0。求n天后能得到的熟练度的和的最大值。首先容易有一个显然的dp状态:\(f......
  • The 2024 ICPC Asia EC Regionals Online Contest (II) - Problem H. Points Selectio
    注意到如果$\text{query}(a,b,c)$为真,那么$\text{query}(\geqa,\geqb,c)$一定为真。从小到大枚举询问中$a$的值,按横坐标从小到大依次加入每个点,维护$f_c$表示最小的$b$满足$\text{query}(a,b,c)$为真。假设当前正在加入点$(x,y,w)$,有$f_{(c+w)\bmodn}=\min(f_{......
  • The 2024 ICPC Asia EC Regionals Online Contest (II) - Problem B. Mountain Bookin
    从$1$到$m$依次考虑每个日期。假设当前正在考虑第$i$天,那么只有第$i$天来访的游客以及指定第$i$天的查询是有用的。将这些游客和查询都提取出来,通过Kruskal重构树可以很方便地在$O(n\logn)$的时间内计算出这些查询的答案。不幸的是,本题还有加边删边操作,无法轻易地......