1919C. Grouping Increases

问题描述

序列XXX,划分成两个字序列A,BA,BA,B,其中惩罚是A,BA,BA,B之中,A[i]<A[i+1],B[i]<B[i+1]A[i] < A[i+1], B[i] < B[i+1]A[i]<A[i+1],B[i]<B[i+1]的个数

思路

  1. 拆分XXX,实际上是个在线的过程,不断的从XXX中拿数字往A,BA,BA,B之中填。

  2. 我们假设A,BA,BA,B的最后一个数字为Al,BlA_l,B_lAl,Bl, 针对元素X[i]X[i]X[i]的插入,下列三种情况进行不同的讨论,不失一般性,我们假设Al<=BlA_l <= B_lAl<=Bl
    情况1:X[i]<=AlX[i] <= A_lX[i]<=Al
    X[i]X[i]X[i]AAA里,因为BlB_lBl可接受的范围一定更广泛

    情况2:X[i]>BlX[i] > B_lX[i]>Bl
    X[i]X[i]X[i]AAA里,因为添加到BBB的末尾,会损失一个大一点的数字

    情况3: Al<X[i]<=BlA_l < X[i] <= B_lAl<X[i]<=Bl
    X[i]X[i]X[i]BBB里,不论到A和B得会到一个负分,该决策优于添加到A,这个在文末证明。

代码

void solve()
{
	int n;
	cin >> n;
	vector<int> v(n + 1);
	for (int i = 1; i <= n; i++)
	{
		cin >> v[i];
	}
    int a, b;
    a = b = INT_MAX;
    int penalty = 0;
    for (int i = 1; i <= n; i++)
    {
        if (a > b) // a <= b
        {
            swap(a, b);
        }
        if (v[i] <= a)
        {
            a = v[i];
        }
        else if (v[i] <= b)
        {
            b = v[i];
        }
        else
        {
            penalty++;
            a = v[i];
        }
    }
    cout << penalty << "\n";
}

证明

情况3我们可以比较两种决策,
决策1:插入A
决策2:插入B

决策2的收益来的比较短,比如下面这种场景
A:[3]A:[3]A:[3]
B:[8]B:[8]B:[8]
X[i]=5X[i] = 5X[i]=5

A:[3]A:[3]A:[3]
B:[8,5]B:[8, 5]B:[8,5]

如果我们下一个数字X[i+1]X[i+1]X[i+1]为7,就得到1点负面收益
A:[3,7]A:[3, 7]A:[3,7]
B:[8,5]B:[8, 5]B:[8,5]


决策1的收益在与后期,比如:

A:[3]A:[3]A:[3]
B:[8]B:[8]B:[8]
X[i]=5X[i] = 5X[i]=5

A:[3,5]A:[3, 5]A:[3,5]
B:[8]B:[8]B:[8]

如果我们下一个数字X[i+1]X[i+1]X[i+1]为7,那么我们决策1就会得到收益
A:[3,5]A:[3,5]A:[3,5]
B:[8,7]B:[8, 7]B:[8,7]

但是如果我们下个数字大于8, 或者小于等于5,我们决策2和决策1会等价,并且决策2会少一点penalty。

比较上面情况, 决策2全方面的大于决策1

证毕

其实可以通过直觉得到结论,因为如果保留BlB_lBl,添加到AAA里,由于每个数字都只受相邻影响,所以BlB_lBl的收最多就1。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值