首页 > 试题广场 >

小美的数组删除

[编程题]小美的数组删除
  • 热度指数:4534 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
\,\,\,\,\,\,\,\,\,\,小美有一个长度为 n 的数组 a_1,a_2,\dots,a_n ,他可以对数组进行如下操作:
\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,● 删除第一个元素 a_1,同时数组的长度减一,花费为 x
\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,● 删除整个数组,花费为 k\times \operatorname{MEX}(a) (其中 \operatorname{MEX}(a) 表示 a 中未出现过的最小非负整数。例如 [0,1,2,4]\operatorname{MEX}3 )。
\,\,\,\,\,\,\,\,\,\,小美想知道将 a 数组全部清空的最小代价是多少,请你帮帮他吧。

输入描述:
\,\,\,\,\,\,\,\,\,\,每个测试文件均包含多组测试数据。第一行输入一个整数 T\ (1\le T\le 1000) 代表数据组数,每组测试数据描述如下:
\,\,\,\,\,\,\,\,\,\,第一行输入三个正整数 n, k, x\ (1 \leq n \leq 2\times 10^5,\ 1 \leq k, x \leq 10^9) 代表数组中的元素数量、删除整个数组的花费系数、删除单个元素的花费。
\,\,\,\,\,\,\,\,\,\,第二行输入 n 个整数 a_1,a_2,\dots,a_n\ (0 \leq a_i \leq n),表示数组元素。
\,\,\,\,\,\,\,\,\,\,除此之外,保证所有的 n 之和不超过 2\times 10^5


输出描述:
\,\,\,\,\,\,\,\,\,\,对于每一组测试数据,在一行上输出一个整数表示将数组中所有元素全部删除的最小花费。
示例1

输入

1
6 3 3
4 5 2 3 1 0

输出

15

说明

\,\,\,\,\,\,\,\,\,\,若不执行操作一就全部删除,\operatorname{MEX}\{4,5,2,3,1,0\}=6,花费 18
\,\,\,\,\,\,\,\,\,\,若执行一次操作一后全部删除,\operatorname{MEX}\{5,2,3,1,0\}=4,花费 3+12
\,\,\,\,\,\,\,\,\,\,若执行两次操作一后全部删除,\operatorname{MEX}\{2,3,1,0\}=4,花费 6+12
\,\,\,\,\,\,\,\,\,\,若执行三次操作一后全部删除,\operatorname{MEX}\{3,1,0\}=2,花费 9+6
\,\,\,\,\,\,\,\,\,\,若执行四次操作一后全部删除,\operatorname{MEX}\{1,0\}=2,花费 12+6
\,\,\,\,\,\,\,\,\,\,若执行五次操作一后全部删除,\operatorname{MEX}\{0\}=1,花费 15+3
\,\,\,\,\,\,\,\,\,\,若执行六次操作一,\operatorname{MEX}\{\}=0,花费 18
import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        StringBuilder sb = new StringBuilder();
        int t = in.nextInt();
        for (int i = 0; i < t; i++) {
            int n = in.nextInt();
            long k = in.nextInt();
            long x = in.nextInt();
            // System.out.println("n:"+n+", k:"+k+", x:"+x);
            HashSet<Integer> set = new HashSet<>();
            int[] as = new int[n];
            for (int j = 0; j < n; j++) {
                as[j] = in.nextInt();
            }
            long min = x * n;
            int cur = 0;
            for (int j = n - 1; j >= 0; j--) {
                set.add(as[j]);
                while (set.contains(cur)) {
                    cur++;
                }
                min = Math.min(x * j + k * cur, min);
                // System.out.println(set);
                // System.out.println("min:"+min+", cur:"+cur);
            }
            sb.append(min);
            sb.append("\n");
        }
        System.out.println(sb.toString());
    }
}

发表于 2024-08-17 00:33:30 回复(2)
from math import inf
import sys

t = int(input())
for epoch in range(t):
    n,k,x = map(int,input().split())
    cnt = [0]*(n+1)
    arr = list(map(int,input().split()))
    for i in arr:
        cnt[i]+=1
    res = inf
    for i in range(n+1):
        if(i>0):
            cnt[arr[i-1]]-=1
        mex = cnt.index(0)
        res = min(res,mex*k+i*x)
    print(res)
发表于 2024-09-13 14:36:19 回复(1)
时空复杂度均为 O(N)。C++。
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <stack>
#include <functional>
#include <math.h>
#include <queue>
#include <deque>
#include <map>
#include <thread>
#include <string.h>
#include <limits.h>
using namespace std;
using ll = long long;
using pii = pair<int,int>;
const int MOD = 1e9+7;
 
 
int main()
{
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        ll k,x;
        cin>>k>>x;
 
        vector<int> a(n);
        vector<int> cnt(n+1);
        for(int i=0;i<n;i++){
            cin>>a[i];
            cnt[a[i]]++;
        }
        int mex;
        for(int i=0;i<=n;i++){
            if(cnt[i]==0){
                mex = i;
                break;
            }
        }
        ll ans = k*mex;
        ll cur = 0;
        for(int i=0;i<n;i++){
            cur += x;
            cnt[a[i]]--;
            if(cnt[a[i]]==0){
                mex = min(mex,a[i]);
            }
            ans = min(ans,cur + k*mex);
        }
        cout<<ans<<endl;
    }
}
发表于 2024-09-11 17:35:31 回复(2)
坑在于整型溢出
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int T = in.nextInt();
        for (int j = 0; j < T; j++) {
            int n = in.nextInt();
            int k = in.nextInt();
            long x = in.nextLong();
            int[] cnt = new int[n + 1];
            int[] arr = new int[n];
            for (int i = 0; i < n; i ++) {
                int val = in.nextInt();
                arr[i] = val;
                cnt[val]++;
            }
            long mex = n;
            for (int i = 0; i <= n; i++) {
                if (cnt[i] == 0) {
                    mex = i;
                    break;
                }
            }
            long minCost = k * mex;
            for (int i = 0; i < n; i++) {
                cnt[arr[i]] --;
                if (arr[i] < mex && cnt[arr[i]] == 0) {
                    mex = arr[i];
                }
                long newRes = (i + 1) * x + mex * k;
                minCost = Math.min(minCost, newRes);
            }
            System.out.println(minCost);
        }
    }
}


发表于 2024-09-02 09:12:24 回复(0)
import java.util.*;

//字符串匹配问题 美团24秋招第一场笔试
public class Main {
    //第一题
    public String matchID(String s) {
        if (s.matches("^[a-zA-Z][0-9]+$")) {
            return "standard";
        } else if (s.matches("^[0-9][a-zA-Z]+$")) {
            return "special";
        } else if (s.matches("^[a-zA-Z][a-zA-Z0-9]+$")) {
            return "mix";
        } else {
            return "invalid";
        }
    }

    //第三题
    long[] mexAns;
    public long deletePayment(long[] nums, long k, long x) {
        int n = nums.length;
        if (n == 0) return 0;
        mexAns=null;
        long ans = Long.MAX_VALUE;
        long payment = Math.min(k * mex(nums, 0), (long) n * x);
        if (payment == 0) return 0;
        for (int i = 1; i < n; i++) {
            ans = Math.min(ans, payment);
            payment = (long) i * x + k * mex(nums, i);
        }

        return ans;
    }


    //mex函数测试通过
    public long mex(long[] nums, int i) {
        if(mexAns == null) {
            mexAns = mexList(nums);
        }
        return mexAns[i];
    }

    public long[] mexList(long[] nums) {
        int n = nums.length;
        if (n == 0) return new long[0];
        Set<Long> set = new HashSet<>();

        long[] dp = new long[n];
        dp[n - 1] = nums[n - 1] == 0 ? 1 : 0;
        set.add(nums[n - 1]);
        for (int i = n - 2; i >= 0; i--) {
            if (dp[i + 1] < nums[i]) {
                dp[i] = dp[i + 1];
                set.add(nums[i]);
            } else {
                long mex = dp[i + 1];
                set.add(nums[i]);
                while (set.contains(mex)) {
                    mex++;
                }
                dp[i] = mex;
            }
        }
        return dp;
    }

    public static void main(String[] args) {
        Main obj = new Main();
        Scanner sc = new Scanner(System.in);
        String nstr = sc.nextLine();
        int n = Integer.parseInt(nstr);
        for (int i = 0; i < n; i++) {
            String str2 = sc.nextLine();
            String[] lenKX = str2.split(" ");
            int len = Integer.parseInt(lenKX[0]);
            long[] nums = new long[len];

            int k = Integer.parseInt(lenKX[1]);
            int x = Integer.parseInt(lenKX[2]);
            String numsStr = sc.nextLine();
            String[] numStr = numsStr.split(" ");

            for (int h = 0; h < len; h++) {
                nums[h] = Long.parseLong(numStr[h]);
            }
            System.out.println(obj.deletePayment(nums, k, x));
        }
//        long[] nums = {4, 5, 2, 3, 1, 0};
//        int k = 3;
//        int x = 3;
//        System.out.println(obj.mex(nums, 0));
//        System.out.println(obj.deletePayment(nums, 3, 3));
    }
}

题目的思路不难,就按照示例的步骤遍历一变数组。重点在于MEX函数的复杂度优化。
三个细节点:
1. 用long保存答案,否则会溢出导致你只能通过2个测试用例
2. 降低MEX的复杂度,并计算一遍MEX将结果保存起来,在遍历数组时让MEX的复杂度为O(1), 整体下来算法的复杂度为O(n) MEX O(N),deletePayment O(N) 
3. 删除数组只能从左到右依次删除,求MEX可以从数组尾端向前进行动态规划(可能也不是,本人实力有限照着动态规划套用)

再有就是一些IO上的细节,比如对于多组数据需要每次重制mexList,等等。希望能帮助到大家。


发表于 2024-09-20 23:54:48 回复(0)
//提供一个动态规划得思路 用set集合去存数组,在遍历dp时候
//dp[i]表示从i到数组结尾未出现过的最小数字 vec[i]!=dp[i+1],dp[i]=dp[i+1],否则在set中从dp[i+1]+1寻找没出现过的最小值,在遍历dp得时候往set中加元素vec[i]
//初始化,因为说的最小非负数,dp[n-1]=vec[n-1]==0?1:0;
//最后是int整型溢出得问题,用long long


#include <algorithm>
#include <climits>
#include <exception>
#include <iostream>
#include <unordered_set>
#include <vector>
#include <cmath>
#include <iomanip>
using namespace std;

int main() {
    long long t;
    cin>>t;
   
    while(t--)
    {
        long long n;
        long long k,x;
        cin>>n>>k>>x;
   
        vector<long long> vec(n);
        for(long long i=0;i<n;i++)
        {
            cin>>vec[i];
        }
        vector<long long> dp(n,0);
        unordered_set<long long> set_;
        dp[n-1]=vec[n-1]==0?1:0;
        set_.insert(vec[n-1]);
        for(long long i=n-2;i>=0;i--)
        {
            set_.emplace(vec[i]);
            if(vec[i]!=dp[i+1])dp[i]=dp[i+1];
            else if(vec[i]==dp[i+1])
            {
                long long need = dp[i+1]+1;
                while((set_.find(need)!=set_.end()))
                {
                    need++;
                }
                dp[i]=need;
            }
        }
       
        long long res=dp[0]*k;
        for(long long i=1;i<n;i++)
        {
            res = min(res,i*x+k*dp[i]);
        }
        res = min(res,n*x);
        cout<<res<<endl;                                    
    }
}

发表于 2024-09-09 11:04:44 回复(0)
#include <iostream>
#include <vector>
#include <unordered_set>
#include <algorithm>
using namespace std;

int main() {
    int t;cin>>t;
    while(t--){
        int n;
        long long k,x;
        cin>>n>>k>>x;
        vector<int> a(n);
        unordered_set<int> u_set;

        for(int i=0;i<=n;++i) u_set.insert(i);

        for(int i=0;i<n;++i){
            cin>>a[i];
            if(u_set.find(a[i])!=u_set.end()) u_set.erase(a[i]);
        }

        vector<int> tmp(u_set.begin(),u_set.end());
        sort(tmp.begin(),tmp.end());
        int mex=tmp[0];

        long long res=k*(long long)(mex);
        for(int i=0;i<n;++i){
            mex=min(mex,a[i]);
            res=min(res,(long long)(i+1)*x+k*(long long)(mex));
        }
        cout<<res<<endl;
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

为什么这个会有问题呢?
发表于 2024-08-21 20:12:17 回复(3)
import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in  = new Scanner(System.in);
        int T =in.nextInt();
        for(int z=0;z<T;z++){
            int n =in.nextInt();
            int k =in.nextInt();
            int x =in.nextInt();
            int[] nums =new int[n];
            for(int i=0;i<n;i++){
                nums[i]=in.nextInt();
            }
            solve(n,k,x,nums);
        }

        in.close();
    }

    static void solve(int n, int k, int x, int[] nums){
        long[] mex = MEX(n,nums);
        long[] dp = new long[n+1];
        for(int i=n-1;i>=0;i--){
            dp[i] = Math.min(mex[i]*k,x+dp[i+1]);
        }
        System.out.println(dp[0]);
    }

    static long[] MEX(int n, int[] nums){
        Set<Integer> set= new HashSet<>();
        long[] mex = new long[n];
        mex[n-1]= nums[n-1]==0? 1: 0;
        if(nums[n-1]>mex[n-1])
            set.add(nums[n-1]);
        for(int i=n-2;i>=0;i--){
            if(nums[i]!=mex[i+1]){
                mex[i]=mex[i+1];
                if(nums[i]>mex[i])
                    set.add(nums[i]);
            }else{
                int tmp = nums[i]+1;
                while(set.contains(tmp)){
                    tmp++;
                }
                mex[i]=tmp;
                if(nums[i]>mex[i])
                    set.add(nums[i]);
            }
        }
        return mex;
    }
}







发表于 2024-08-16 17:25:23 回复(0)
T = int(input())
# print('T is ', T)
for _ in range(T):
    line2 = [int(i) for i in input().split()]
    # print('line2 is ', line2)

    n = line2[0]
    k = line2[1]
    x = line2[2]
    # print('n k x is ', n, k, x)

    line3 = [int(i) for i in input().split()]
    # print('line3 is ', line3)

    mex = [0]*len(line3)

    min_num = 0
    while min_num in set(line3):
        min_num += 1

    mex[0] = min_num
    cost = k*mex[0]

    for j in range(1, len(line3)):
        if line3[j-1] < min_num and line3[j-1] not in set(line3[j:]):            
            min_num = line3[j-1]
            mex[j] = min_num
        else:
            mex[j] = min_num
        
        cost = min(cost, j*x + k*mex[j])

    print(cost)
正向遍历

发表于 2025-07-08 14:17:09 回复(0)
import sys
num = input()
num = int(num) for i in range(num):
    inp = input()
    inp = inp.split()
    number = int(inp[0])
    allcost = int(inp[1])
    cost = int(inp[2])
    arr = input()
    arr = arr.split() for j in range(len(arr)):
        arr[j] = int(arr[j])
    num_set = set(arr)
    n = len(num_set) for j in range(n + 1): if j not in num_set:
            mex = j break  mincost = allcost * mex for j in range(number): if arr[j] > mex: continue  else:
            num_set = set(arr[j + 1:]) if arr[j] not in num_set:
                mex = arr[j]
                fincost = cost * (j + 1) + mex * allcost
                mincost = min(mincost, fincost)
    mincost = min(number * cost, mincost) print(mincost)
发表于 2025-05-16 21:35:21 回复(0)
为什么测试样例中会有那么多0?怎么想都不可能有0 cost吧?
发表于 2025-05-15 20:10:08 回复(1)
有没有uu帮我看看这个为什么17/20

t = int(input())
 
def mex(a):
    num_set = set(a)
    i = 0
    whilei in num_set:
        i += 1
    returni
 
for_ in range(t):
    n,k,x = map(int,input().strip().split())
    arr = list(map(int,input().strip().split()))
    # 代表执行i次后全部删除
    m = mex(arr[:]) # 当前最小非负整数位置
    res = min(n*x,m*k)
    fori in range(1,n):
        ifarr[i-1] < m:
            m = arr[i-1]
            res = min(res,k*m+x*i)
   
    print(res)
 
# 17/20   

编辑于 2025-04-04 17:15:59 回复(0)
那种机构备用于提升大模型的处理超长文本的能力
发表于 2025-03-22 19:28:03 回复(0)
想到了dp,没想到hash,看了别人的解答整了个C++的:
#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int MOD = 1e9+7;
long long MEX(long long hashmap[])
{

    for(int i=0; i<200005; i++)
    {
        if(hashmap[i] == 0)
        {
            return i;
        }
    }
    return -1;
}
int main() {
    int T;
    cin >> T;
    for(int i=0; i<T; i++)
    {
        int n, k, x;
        cin >> n >> k >> x;
        vector<long long> nums;
        long long hashmap[200005] = {0};
        for(int j=0; j<n; j++)
        {
            long long tmp;
            cin >> tmp;
            nums.push_back(tmp);
        }
        vector<long long> dp(n+1, 0);
        dp[n] = 0;
        for(int j=n-1; j>=0; j--)
        {
            hashmap[nums[j]]++;
            dp[j] = min(dp[j+1] + x, k*MEX(hashmap));
        }
        cout<<dp[0]<<endl;

    }
}

// 64 位输出请用 printf("%lld")


发表于 2025-03-22 00:27:02 回复(0)
有没有人和我一样只有列17的最后一个答案不一样啊》真的找不出是什么bug啊
发表于 2025-02-27 15:02:22 回复(4)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

long long cal_min_cost(int a_num, long long* m_a, long long* m_check, long long c_coe, long long c_single) {
    long long min_cost = LLONG_MAX;
    for (int p = 0; p <= a_num; p++) {
        int m = 0;  // 从0开始检查
        while (m <= a_num && m_check[m] > 0) {
            m++;
        }
        long long cost = c_single * p + c_coe * m;
        if (cost < min_cost) {
            min_cost = cost;
        }
        if (m_a[p] >= 0 && m_a[p] <= a_num) {
            m_check[m_a[p]]--;
        }
    }
    return min_cost;
}

int main() {
    int T;
    scanf("%d", &T);
    for (int i = 0; i < T; i++) {
        int a_num;
        long long c_coe, c_single;
        scanf("%d %lld %lld", &a_num, &c_coe, &c_single);

        // 动态分配数组
        long long* a = (long long*)malloc(a_num * sizeof(long long));
        long long* check = (long long*)calloc(a_num + 2, sizeof(long long));  // 多分配一些空间防止越界

        for (int j = 0; j < a_num; j++) {
            scanf("%lld", &a[j]);
            if (a[j] <= a_num) {  // 确保不越界
                check[a[j]]++;
            }
        }

        long long min_cost = cal_min_cost(a_num, a, check, c_coe, c_single);
        printf("%lld\n", min_cost);

        free(a);
        free(check);
    }
    return 0;
}

编辑于 2025-02-26 20:32:45 回复(0)
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int t = in.nextInt(); // 读取测试数据的组数 StringBuilder sb = new StringBuilder(); for (int i = 0; i < t; i++) { int n = in.nextInt(); // 数组的长度 long k = in.nextInt(); // 某个参数 long x = in.nextInt(); // 另一个参数 int[] as = new int[n]; for (int j = 0; j < n; j++) { as[j] = in.nextInt(); // 读取数组元素 } // 使用一个布尔数组来标记哪些数字已经出现过 boolean[] used = new boolean[n + 1]; // 假设数组元素都是非负的 long minCost = Long.MAX_VALUE; // 初始化最小成本为一个很大的值 // 遍历数组,计算每种可能的最小成本 for (int j = 0; j < n; j++) { // 找到下一个未使用的数字作为cur int cur = 0; while (used[cur]) { cur++; } // 计算当前选择下的成本 long cost = x * j + k * cur; // 更新最小成本 if (cost < minCost) { minCost = cost; } // 标记当前数字as[j]为已使用 // 注意:这里我们假设as[j]的值都在0到n-1的范围内,或者进行了适当的映射 // 如果as[j]的值可能超出这个范围,需要调整used数组的大小或使用其他方法 used[as[j]] = true; } // 将结果添加到StringBuilder中 sb.append(minCost).append("\n"); } // 输出所有结果 System.out.print(sb.toString()); } }
发表于 2025-01-27 12:22:17 回复(0)

刚开始写很容易越界,得不断debug

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Main {
    int k, x;
    List arr;
    int[] counts;
    public static void main(String[] args) {
        Main m = new Main();
        m.task();
    }
    public void task() {
        try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
            int T = Integer.parseInt(br.readLine());
            for (int i = 0; i < T; ++i) {
                List first = Arrays.stream(br.readLine().split(" "))
                                      .map(Integer::parseInt)
                                      .collect(Collectors.toList());
                k = first.get(1);
                x = first.get(2);
                arr = Arrays.stream(br.readLine().split(" "))
                      .map(Integer::parseInt)
                      .collect(Collectors.toList());
                counts = new int[first.get(0) + 1];
                for (int num : arr) {
                    ++counts[num];
                }
                int MEX = counts.length; // 默认都存在
                for (int j = 0; j < counts.length; ++j) {
                    if (counts[j] == 0) {
                        MEX = j;
                        break;
                    }
                }
                System.out.println(minCost(0, MEX));
            }
        } catch (IOException e) {
        }
    }
    //递归
    private long minCost(int i, int MEX) {
        if (i == arr.size()) {
            return 0;
        }
        int nextMEX = MEX;
        int elem = arr.get(i);
        if ((--counts[elem] == 0) && (elem < MEX)) {
            nextMEX = elem;
        }
        return Math.min((long)k * MEX, x + minCost(i + 1, nextMEX));
    }
}
编辑于 2025-01-06 22:08:40 回复(0)
来个优先队列的解法
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

int main() {
    int size;
    cin >> size;

    for (int T = 0; T < size; ++T) {
        int n, k, x;
        cin >> n >> k >> x;
        priority_queue<int, vector<int>, greater<>> q;
        vector<int> num;
        for (int i = 0; i < n; ++i) {
            int t;
            cin >> t;
            num.push_back(t);
        }
        long long ans = n * x, now = 0;
        for (int i = n - 1; i >= 0; --i) {
            int t = num[i];
            q.push(t);
            while (!q.empty() && q.top() <= now) {
                if (q.top() == now) ++now;
                q.pop();
            }
            ans = min(ans, (long long)i * x + k * now);
        }
        cout << ans << endl;
    }

}


发表于 2024-12-19 22:45:00 回复(0)
DP, 首先求出MEX数组, MEX[ i ]=mex( [a_i,...a-_n] ) ,再求dp数组 dp[ i ]=min{ x+dp[i+1], k*MEX[i] }

#include <iostream>
#include<set>
#include<vector>
using namespace std;
int main() {
    long long T, n, k, x;
    cin >> T;
    for (int loop = 0; loop < T; loop++) {
        cin >> n;
        cin >> k;
        cin >> x;
        
        // input
        vector<long long>input(n, 0);
        for (long long i = 0; i < n; i++) {
            cin >> input[i] ;
        }

        // cal mex
        vector<long long >MEX(n, 0);
        set<long long> isExist;
        long long tmpMEX = 0;
        for (long long i = n - 1; i >= 0; i--) {
            isExist.insert(input[i]);
            while (isExist.find(tmpMEX) != isExist.end()) {
                tmpMEX++;
            }
            MEX[i] = tmpMEX;
        }

        // cal dp(i)=res([a_i,...,a_n])
        vector<long long>dp(n, 0);
        dp[n - 1] = min(x, k * MEX[n - 1]);
        for (long long i = n - 2; i >= 0; i--) {
            dp[i] = min(
                        x + dp[i + 1],
                        k * MEX[i]
                    );
        }
        cout << dp[0] << endl;
    }
    return 0;
}


发表于 2024-10-01 17:14:02 回复(0)