/* 问题描述: 小美有一个长度为 n 的数组 a1,a2,.·,an ,他可以对数组进行如下操作: 1.删除第一个元素 a1,同时数组的长度减一,花费为x 2.删除整个数组,花费为k*MEX(a),其中MEX(a)表示a中未出现过的最小非负整数。例如[0,1,2,4]的 MEX为3。 小美想知道将 a 数组全部清空的最小代价是多少。 输入描述: 每个测试文件均包含多组测试数据。第一行输入一个整数T代表数据组数,每组测试数据描述如下第二行输入三个正整数:n,k,x 代表数组中的元素数量、删除整个数组的花费系数、删除单个元素的花费。第三行输入n个整数 a1, a2,...,an表示数组元素。 除此之外,保证所有的a之和不超过 2x105. */ /* 思路:动态规划+维护最小未出现的整数 dp[i]表示从i往后考虑的最小花费,最后的最小花费就是dp[0]和直接删除后续所有元素的最小值 对于删除后续所有的元素的选项,我们必须要知道mex是多少,可以在更新dp的过程中,用一个变量不断的更新当前的最小未出现的整数 虽然这里出现了两次循环的嵌套,但是并不会重置参数,因此复杂度是O(n) */ #include #include #include #include using namespace std; int main() { int T; cin >> T; // 读取测试数据组数 while (T--) { long long n, k, x; cin >> n >> k >> x; vector a(n); for (int i = 0; i < n; ++i) { cin >> a[i]; } // 动态规划数组dp[i]表示从i往后考虑的最小花费,最后最小花费就是dp[0]或者直接删除后续所有元素 vector dp(n + 1, LLONG_MAX); dp[n] = 0; int suffix_mex = 0; set vst; for (int i = n-1; i >= 0; --i) { vst.insert(a[i]); while(vst.count(suffix_mex)){ suffix_mex++; } dp[i] = min(dp[i + 1] + x, k * suffix_mex); } // 输出最小花费 cout << dp[0] << endl; } return 0; }