• [Poetize6] IncDec Sequence题解


    欢迎来看看呀

    题目链接

    这道题可以转化为求出原数列的差分数组,然后使得最终得到的数列中所有数都相等就可以转化为将差分数组中的所有数都变成零,并求出最小的操作次数以及最终有多少种方式

    我们再来看一看题中所说的操作,选定一个区间([l,r])并将其中的数+1或-1,设差分数组(b[i]),那么可以发现这个操作的本质就是将(b[l])加一或减一以及将(b[r+1])减一或加一,为了使最终操作次数最少,尽量要选出差分数组里的一个正数和一个负数来执行这个操作

    举个例子,差分数组0 3 -2 3 0 -5 -3

    我们执行上述操作后可以得到另外几个差分数组0 0 0 0 0 -1 -3或者0 0 -2 0 0 -2 0,根据题目的要求可以很显然的发现通过这两种方式求的的最终答案是一样的,设差分数组中正数的和为(s1),负数的和的绝对值为(s2),那么执行这一种操作的次数即为(min(s1,s2))

    然后还有两种很重要的操作,第一种是选择([0,i])区间进行加减操作,第二种是选择([i,n])区间,可以将差分数组中的一个数变为零,执行这一种操作的的次数即为(|s1-s2|),并且所得结果的种数也取决于这两种操作,最高可以达到(max(s1,s2)),最低可以达到(min(s1,s2)),所以答案种数便为(|s1-s2|+1)

    综上所述,(ans1=min(s1,s2)+|s1-s2|=max(s1,s2)),(ans2=|s1-s2|+1)

    代码比较简单

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    int n,a[100003],b[100003],s1,s2;
    signed main()
    {
    	scanf("%d",&n);
    	for(int i=1; i<=n; i++)
    	{
    		scanf("%d",&a[i]);
    		if(i!=1)
    		{
    			b[i]=a[i]-a[i-1];
    			if(b[i]>0)
    				s1+=b[i];
    			else
    				s2-=b[i];
    		}
    	}
    	cout<<max(s1,s2)<<endl<<abs(s1-s2)+1;
    	return 0;
    }
    
  • 相关阅读:
    WEB开发中合理选择图片格式
    Ext.ux.form.LovCombo bug修正
    Ext.grid.PropertyGrid 扩展
    BLOG代码高亮
    Box2D教程1创建碰撞世界
    Box2D教程2鼠标交互
    Box2D教程5碰撞检测
    Box2D教程3刚体绑定外观
    管窥HTML5
    Box2D教程4复杂刚体的复杂外观
  • 原文地址:https://www.cnblogs.com/dzice/p/12002320.html
Copyright © 2020-2023  润新知