AcWing——4786. 闯关

93 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 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;
}
​