开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第34天,点击查看活动详情
AcWing——4786. 闯关
4786. 闯关
某综艺频道推出了一个闯关活动。
活动一共包含 n个关卡(编号 1∼n),其中 m 个关卡为特殊关卡。
每个关卡都有一个通关分数,其中第 i 个关卡的通关分数为 ai。
挑战者可以自由决定所有关卡的具体挑战顺序,并且每通过一个关卡就可以获得该关卡的通关分数。
值得注意的是,当挑战者即将挑战的关卡是特殊关卡时,如果挑战者当前已经获得的总分数大于该特殊关卡的通关分数,则挑战者可以对该关卡的通关分数进行一次修改,修改后的新分数不能小于原分数,也不能大于挑战者当前已经获得的总分数。
请你计算并输出挑战者通过所有关卡获得的总分数的最大可能值。
输入格式
第一行包含两个整数 n,m。
第二行包含 n 个整数 a1,a2,…,an,表示每个关卡的通过分数。
第三行包含 m 个整数 b1,b2,…,bm,表示每个特殊关卡的编号。
输出格式
一个整数,表示挑战者通过所有关卡获得的总分数的最大可能值。
保证最终答案不超过 26^3−1。
数据范围
前 4 个测试点满足 1≤n≤4。 所有测试点满足 1≤n,m≤100,m≤min(n,30),1≤ai≤10^7,1≤bi≤n,bi 两两不同。
输入样例1:
4 1
1 3 7 5
3
输出样例1:
18
问题解析
贪心做法。
我们先通关所有的非特殊关卡,然后对所有的特殊关卡进行降序排序。
- 如果当前特殊关卡的分数大于我们的分数,就不进行操作把它直接加到我们的分数上。
- 如果当前特殊关卡的分数小于我们的分数,就把它的分数修改成和我们当前总分数一样。
AC代码
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include <random>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<fstream>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>
#include<bitset>
//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
#define endl '\n'
#define int ll
#define PI acos(-1)
#define INF 0x3f3f3f3f
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 2e5 + 50, MOD = 998244353;
int a[N];
void solve()
{
int n, m, sum = 0, x;
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
sum += a[i];
}
vector<int>v;
for (int i = 1; i <= m; i++)
{
cin >> x;
sum -= a[x];
v.push_back(a[x]);
}
sort(v.begin(), v.end(), greater<int>());
for (auto& i : v)
{
if (sum < i)sum += i;
else sum *= 2;
}
cout << sum << endl;
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t = 1;
//cin >> t;
while (t--)
{
solve();
}
return 0;
}