首页 > 其他分享 >Codeforces Round 887 (Div. 1)C. Ina of the Mountain(数据结构,反悔贪心)

Codeforces Round 887 (Div. 1)C. Ina of the Mountain(数据结构,反悔贪心)

时间:2023-08-28 12:34:20浏览次数:36  
标签:std Mountain 887 int Codeforces cin 反悔 操作 贪心

题目链接:https://codeforces.com/problemset/problem/1852/C

 

题意:

 

给定一个长度为n的序列和正整数k;

 

每次可以选取任意一个区间,将区间内每个数减1;

 

如果出现一个数变成0,那么那个数变成k;

 

问至少操作多少次可以使得每个数变成k;

 

分析:

 

将每个数值抽象为对应高度的矩形(k 看作 0)并按索引排列在一起,假设数字变为 0 后变成 k,目标就变为了“将所有数字变为 0”,那么总操作数为所有相邻矩形高度上升的总和。

 

例如:1 2 3 4 在k为5的时候,操作次数为4,1 2 3 4 1 2 在k为5 的时候操作次数为4 + 2  = 6;

 

那么我们现在就需要分析如何将这个操作次数进行减少;

 

我们将“高度变为0后转变为k”这个条件替换成增加k(可以看出是等价的);

 

那么我们可以进行如下操作:

 

假设已经确定了i个的操作次数,那么现在考虑第i+1个,设第i+1个的高度为h【i+1】,那么

 

1:h【i+1】<=h【i】,不进行任何操作;

 

2:h【i+1】>h【i】:

  

  a:不增加k,将答案增加h【i+1】-h【i】;

  

  b:选择一个j<=i,使得 k + h【j】 - h【j-1】 - max(0,h【j】-h【j-1】)这个值最小为 f【i】,并将 j 到 i中的高度都增加 k ,然后答案增加 f【i】;

 

在 a 和 b内选择增加最小的一种方案;

 

但是这个复杂度是O(n^2)是无法通过此题的,考虑单调队列优化;

 

每个f【i】最多被选择一次,故复杂度是O(nlogn);

 

代码:

 

 

#include<bits/stdc++.h>

#define int long long

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);

    int T;
    std::cin >> T;
    while (T--) {
        int n, k;
        std::cin >> n >> k;
        std::vector<int> a(n + 1, 0);
        for (int i = 1; i <= n; ++i)std::cin >> a[i], a[i] %= k;

        std::priority_queue<int, std::vector<int>, std::greater<int> > Q;

        int ans = 0;
        for (int i = 1; i <= n; ++i) {
            if (a[i] == a[i - 1])continue;
            if (a[i] < a[i - 1])Q.push(k + a[i] - a[i - 1]);
            else Q.push(a[i] - a[i - 1]), ans += Q.top(), Q.pop();
        }

        std::cout << ans << "\n";
    }

    return 0;
}

 

使用单调队列来优化是反悔贪心比较常见的方法,读者感兴趣可以去了解一下:)

 

标签:std,Mountain,887,int,Codeforces,cin,反悔,操作,贪心
From: https://www.cnblogs.com/ACMER-XiCen/p/17660495.html

相关文章

  • Codeforces Round 892 (Div. 2)E. Maximum Monogonosity(动态规划,数学)
    题目链接:https://codeforces.com/contest/1859/problem/E 题意: 有长度为n的a和b俩个序列,定义f【l,r】=abs(a【l】-b【r】)+abs(b【l】-a【r】); 给正整数k,求 不相交的区间且  所有  区间的长度 的 和 为k的最大值 是多少? 分析: 这里借鉴一个佬......
  • Educational Codeforces Round 151 (Rated for Div. 2)E. Boxes and Balls(数学,动态规
    题目链接:https://codeforces.com/contest/1845/problem/E 题意: 给定长度为n且只含0和1的数组,你可以进行以下操作: 交换相邻的0和1; 给正整数k,问经过k次操作后,会有多少种本质不同的结果; 分析: 如果1比0多,我们可以把他们取反(让0比1多,结果是一样的) 设计状态dp[i][j......
  • Codeforces Round 885 (Div. 2)E. Vika and Stone Skipping(数学,质因数分解)
    题目链接:https://codeforces.com/problemset/problem/1848/E 大致题意: 打水漂,某人在海岸线以f(正整数)的力量扔出石头,会在f,f+(f-1),f+(f-1)+(f-2),........,f+(f-1)+.....+2+1,的位置接触水面; 现在给出坐标x和q次询问,每次询问给出一个y值,将x=x*y;假设石头在x的位置接触水面,问有多少......
  • Educational Codeforces Round 119
    今天只有3题,有点遗憾,D题几乎一眼切,但是时间不够,分类讨论没写完,vp结束几分钟后写出来。A题开始还以为要并查集,后面发现只有一个N不行B题漏写括号WA一发C题感觉不好写啊,因为直接计算可能会爆,所以要先从后往前,确定边界,然后就是跟普通的填数差不多,二分一下。又是找串,还得特别小心......
  • Codeforces Round 885 (Div. 2) F. Vika and Wiki(数学,倍增)
    题目链接:https://codeforces.com/problemset/problem/1848/F 大致题意:长度为n(n是2的幂次),每轮让a【i】=a【i】^a【i%n+1】,(^为异或)问需要操作多少次后可以使得每个数为0; 解题思路:我们来观察:第一次相当于:a【i】=a【i】^a【i+1】,a【i+1】=a【i+1】^a【i+2】第二次......
  • Educational Codeforces Round 152 (Rated for Div. 2)E. Max to the Right of Min(数
    题目链接:https://codeforces.com/problemset/problem/1849/E 大致题意: 长度为n的序列,求有多少个区间满足区间最大值在区间最小值的右边? 解题思路: (此题有使用线段树等其他做法,本处使用的是单调栈做法) 我们先求出每个a【i】的左边的比他小的LMIN,左边比他大的LMAX,右......
  • Codeforces Round 889 (Div. 1)C. Expected Destruction(期望,动态规划)
    题目链接:https://codeforces.com/problemset/problem/1854/C 大致题意: 有一个集合S,和一个上界m; 现在每秒钟可以进行一次如下操作: 1:等概率的选取S中的一个元素x;2:将x从S中移走;3:如果x+1不大于m并且x+1不在S中,那么添加x+1在S里面 问期望多少秒钟后可以使得S为空集(答......
  • Codeforces Round 889 (Div. 1) B. Earn or Unlock(dp,bitset)
    题目链接:https://codeforces.com/problemset/problem/1854/B 题目大致题意: 有n张卡牌从上到下堆叠,每张卡片有锁或不锁俩种状态,一开始第一张是不锁的;对最上面的卡牌,如果他是不锁的状态,那么可以进行俩种操作:1:从上到下,将v张被锁的卡牌解锁;2:获取v点能量现在求能获得的最大的......
  • Codeforces Round 890 (Div. 2) supported by Constructor Institute D. More Wrong(交
    题目链接:https://codeforces.com/contest/1856/problem/D 大致题意:这是一道交互题,有1~n的排列p,对于每次询问,你可以花费(R-L)2的代价去得到区间【L,R】之内的逆序对的个数,你需要在5n2的代价内得到n的位置。 初步思路: 首先我们来思路,在什么时候,我们可以确定那个位置是n。假......
  • Codeforces Round 894 (Div. 3)
    A.\(n\)个长为\(m\)的字符串,判断存在\(i,j,k,l\)有\(1\leqi<j<k<l\leqm\),满足这四列的字符串分别有\(v,i,k,a\)。小细节的题。时间复杂度\(O(n^2)\)。view#include<bits/stdc++.h>#defineREP(i,A,N)for(inti=(int)A;i<=(int)N;i+......