BSOJ7686 开挂

题目描述

在这里插入图片描述

科技

分析

很容易想到要对每个重复的数进行操作,但如何操作呢?
容易想到:对每一个重复的树,我们贪心地为其寻找最近的一个空位,最后对操作距离排序,用最大距离和最小代价组合。
但遗憾的是:这是一个错解。
我们发现:

3 3 4 4 6 10
1 2 3 4 5 6

是一个反例,原因在于:代价不同,总移动距离相同时,应让最大的距离尽可能大,这样总代价才会尽可能小。
于是我们发现,对每一个空缺,应优先选择离其最近的没有地方放的数,这样,最大的数就会尽可能大。
这是一种先进后出的结构,于是,我们可以想到,用栈来模拟这一过程
具体来说,我们用栈存储每一个有重复的数,对每一个空缺,为其填上栈顶元素,最后排序移动距离。
最后
a n s = ∑ i = 1 m h i × b m − i + 1 ans = \sum_{i = 1}^m h_i \times b_{m - i + 1} ans=i=1mhi×bmi+1

AC代码

#include<bits/stdc++.h>
using namespace std;
const int N = 1000006;
unsigned long long n,a[N],b[N],h[N],hz;
stack<unsigned long long>s;
int main()
{
    scanf("%llu",&n);
    for(unsigned long long i = 1;i <= n;i++)
        scanf("%llu",&a[i]);
    for(unsigned long long i = 1;i <= n;i++)
        scanf("%llu",&b[i]);
    unsigned long long tmp;
    sort(a + 1,a + 1 + n);
    for(unsigned long long i = 2;i <= n;i++) {
        if(a[i - 1] == a[i])
            s.push(a[i]);
        for(int j = a[i - 1] + 1;j < a[i];j++) {
            if(s.empty())
                break;
            tmp = s.top();
            s.pop();
            h[++hz] = j - tmp;
        }
    }
    for(unsigned long long j = a[n] + 1;;j++) {
        if(s.empty())
            break;
        tmp = s.top();
        s.pop();
        h[++hz] = j - tmp;
    }
    sort(h + 1,h + hz + 1);
    sort(b + 1,b + n + 1);
    unsigned long long ans = 0;
    for(unsigned long long i = hz;i;i--)
        ans = ans + h[i] * b[hz - i + 1];
    printf("%llu\n",ans);
    return 0;
}
  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值