zoukankan      html  css  js  c++  java
  • 题解 P4552 【[Poetize6] IncDec Sequence】

    Solution IncDec Sequence

    题目大意:给定一个序列,你可以将一段子序列集体(+1)(-1),求最小的操作次数使得所有数相等,以及操作方案数

    差分


    分析:

    区间加减不好考虑,我们可以考虑差分

    令原数组(val[0] = 0),差分数组(d[i] = val[i] - val[i - 1])

    然后问题就变成了,给你一个序列,每次可以将(1)个数(+1)同时将另一个数(-1),求最小操作次数使得所有数下标不为(1)的数为(0)

    我们发现,这种方式可以同时改变(2)个数,应当优先采用

    (q = sum d[i] quad | quad d[i] > 0 ; and ; i eq 1),(p = sum d[i] quad | quad d[i] < 0 ; and ; i eq 1)

    这种方法最多采用(min(p,q))

    然后考虑剩下的,这个需要(|p-q|)

    所以需要(min(p,q) + |p -q| = max(p,q))

    方案:

    方案取决于剩下的数,显然剩下的都和(d[1])同号了,有些可以作用于(d[1]),有些可以作用于(d[n + 1]),所以有(|p - q| + 1)种不同的(d[1])取值,所以方案有(|p - q| + 1)

    #include <algorithm>
    #include <cstdio>
    #include <cctype>
    using namespace std;
    typedef long long ll;
    const int maxn = 1e5 + 100;
    ll val[maxn],d[maxn],sum,vsum;
    int n;
    int main(){
    	scanf("%d",&n);
    	for(int i = 1;i <= n;i++)scanf("%lld",val + i);
    	for(int i = 2;i <= n;i++){
    		d[i] = val[i] - val[i - 1];
    		if(d[i] > 0)sum += d[i];
    		else vsum -= d[i];
    	}
    	printf("%lld
    ",max(sum,vsum));
    	printf("%lld
    ",abs(sum - vsum) + 1);
    	return 0;
    }
    
  • 相关阅读:
    [数据结构]线性表
    对C语言中指针的一些新认识
    Qt做动画旋转旋转图片
    延时程序执行Qt
    关于部分网页打不可的问题
    关于QString中的arg()函数使用方法
    Qt5.3.0 for Android开发环境配置
    QMenu,contextmenuevent,窗体透明
    Qt自定义窗体,边框,圆角窗体
    一个良好的团队
  • 原文地址:https://www.cnblogs.com/colazcy/p/11628345.html
Copyright © 2011-2022 走看看