zoukankan      html  css  js  c++  java
  • Codeforces Round #688 (Div. 2)B. Suffix Operations(思维+贡献)

    B. Suffix Operations

    题意

    给你n个数,然后有两个规则:

    • 给后缀增1
    • 给后缀减1

    其中有一个特殊操作,可以任意修改一个数字。

    问你使n个数变为相同的最小操作书是多少。

    思路

    考虑不加特殊操作的使(a_{i+1})变为(a_i)的最小代价,(ans = abs(a_{i + 1} - a_i) + abs(a_{i+ 2}- a{i +1})...abs(a_{n} - a_{n - 1})),将(a_{i+1})变为(a_i)后,要使(a_{i+1})之后的也变为(a_i)只需要将其变为前一个数,因为整个过程是相对的。

    考虑加入特殊操作,将任意一个数变为变一个数。

    这里为什么是要变为前一个数呢?考虑变一个其他位置的数变为任意数,那么可能在原基础需要增加操作,但是变为前一个数一定是减小操作。所以这里是变为前一个数。

    加入特殊操作后考虑将(a_{i+1})变为(a_i),然后考虑其他位变化(a_{i+2})变为(abs(a_{i + 2} - a{i}))其他的保持不变,原本将(a_{i+1},a_{i+2})变为(a_i)需要的代价是(abs(a_{i + 1} - a_i) + abs(a_{i + 2} - a_{i + 1})),二者差值的最大值就是可以省的最大值。

    需要特殊考虑第一位和最后一位

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 2e5 + 100;
    typedef long long LL;
    //#define int long long
    int a[N];
    void solve() {
    	int n; cin >> n;
    	for (int i = 1; i <= n; ++i) cin >> a[i];
    	LL ans = 0;
    	for (int i = 2; i <= n; ++i) ans += abs(a[i] - a[i - 1]);
    	int ma = 0;
    	for (int i = 2; i < n; ++i) {
    		ma = max(ma, abs(a[i + 1] - a[i]) + abs(a[i] - a[i - 1]) - abs(a[i + 1] - a[i - 1]));
    	}
    	ma = max(ma, abs(a[2] - a[1]));
    	ma = max(ma, abs(a[n] - a[n - 1]));
    	cout << ans - ma << endl;
    
    }
    signed main() {
    	ios::sync_with_stdio(0);
    	cin.tie(0);
    	int T = 1;
    	cin >> T;
    	while (T--) {
    		solve();
    	}
    
    }
    

  • 相关阅读:
    字符串转json
    如何解决写好的脚本上传Linux执行出错?
    Windows查看端口并开放端口
    解决mysql遇到非root权限无法登录mysql数据库的问题
    raid配置
    Python实现根据时间移动/复制一个文件夹的文件--模拟大并发数据
    ffmpeg基本命令学习
    pytest学习--pytest的skip和skipif
    多项式全家桶学习笔记(How EI's poly works)
    具体数学难度评分
  • 原文地址:https://www.cnblogs.com/waryan/p/14296640.html
Copyright © 2011-2022 走看看