Make It Permutation

Make It Permutation

题面翻译

给定一个长为 n n n 的序列 a a a,你可以进行以下两个操作:

  1. 删除 a a a 中的任意一个数字,花费为 c c c

  2. a a a 的任意位置插入一个数字,花费为 d d d

求最后得到一个任意长度的排列的最小花费。

注:最终排列长度不能为 0 0 0,但操作中序列长度可以为 0 0 0

题目描述

You have an integer array $ a $ of length $ n $ . There are two kinds of operations you can make.

  • Remove an integer from $ a $ . This operation costs $ c $ .
  • Insert an arbitrary positive integer $ x $ to any position of $ a $ (to the front, to the back, or between any two consecutive elements). This operation costs $ d $ .

You want to make the final array a permutation of any positive length. Please output the minimum cost of doing that. Note that you can make the array empty during the operations, but the final array must contain at least one integer.

A permutation of length $ n $ is an array consisting of $ n $ distinct integers from $ 1 $ to $ n $ in arbitrary order. For example, $ [2,3,1,5,4] $ is a permutation, but $ [1,2,2] $ is not a permutation ( $ 2 $ appears twice in the array), and $ [1,3,4] $ is also not a permutation ( $ n=3 $ but there is $ 4 $ in the array).

输入格式

Each test contains multiple test cases. The first line contains a single integer $ t $ ( $ 1 \le t \le 10^4 $ ) — the number of test cases. Their description follows.

The first line of each test case contains three integers $ n $ , $ c $ , $ d $ ( $ 1 \le n \le 10^5 $ , $ 1 \le c,d \le 10^9 $ ).

The second line of each test case contains $ n $ integers $ a_{1}, a_{2}, \ldots, a_{n} $ ( $ 1 \le a_{i} \le 10^9 $ ).

It is guaranteed that the sum of $ n $ over all test cases does not exceed $ 2 \cdot 10^5 $ .

输出格式

For each test case, output in one line the minimum cost to make the final array a permutation.

样例 #1

样例输入 #1

8
3 3 3
1 2 3
5 1 5
1 2 3 5 6
5 2 3
1 1 1 3 3
5 1 10
2 4 6 8 10
6 2 8
7 3 5 4 4 8
4 10 1
1 2 6 7
4 3 3
2 5 8 7
2 1000000000 1
1000000000 1

样例输出 #1

0
2
8
14
20
3
12
999999998

思路:
我们分析得一旦把后面的某一个数给选择了加入数之后那么它前面就不能再删除了,所以我们一次遍历选择一个点作为可删除的点的一个边界

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#define int long long
using namespace std;
int n, tt, c, d;
int w[2000005];//数值
int a[2000005];
int s[2000005];//中间部分
int t[2000005];//头部部分
signed main()
{
	cin >> tt;
	while (tt--)
	{
		cin >> n >> c >> d;
		for (int i = 1; i <= n; i++) cin >> w[i];
		sort(w + 1, w + 1 + n);
		int k = 1;
		int temp =-1;
		for (int i = 1; i <= n; i++)
		{
			if (temp != w[i]) a[k++] = w[i], temp = w[i];//去重
			else continue;
		}
		k--;
		//for (int i = 1; i <= k; i++) cout << a[i] << " ";
		//cout << endl;
		//a[0] = 0;
		int ans = (n - k) * c;//重复的部分一定是删除
		int res = k * c + d;//全删然后加一个'1'
		for (int i = 1; i <= k; i++) 
		res = min(res, c * (k - i) + d * (a[i] - i));
		cout << res + ans << endl;;
	}
	return 0;
}
  • 11
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值