闯关

73 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第29天,点击查看活动详情 某综艺频道推出了一个闯关活动。

活动一共包含 nn 个关卡(编号 1∼n1∼n),其中 mm 个关卡为特殊关卡。

每个关卡都有一个通关分数,其中第 ii 个关卡的通关分数为 aiai。

挑战者可以自由决定所有关卡的具体挑战顺序,并且每通过一个关卡就可以获得该关卡的通关分数。

值得注意的是,当挑战者即将挑战的关卡是特殊关卡时,如果挑战者当前已经获得的总分数大于该特殊关卡的通关分数,则挑战者可以对该关卡的通关分数进行一次修改,修改后的新分数不能小于原分数,也不能大于挑战者当前已经获得的总分数。

请你计算并输出挑战者通过所有关卡获得的总分数的最大可能值。

输入格式

第一行包含两个整数 n,mn,m。

第二行包含 nn 个整数 a1,a2,…,ana1,a2,…,an,表示每个关卡的通过分数。

第三行包含 mm 个整数 b1,b2,…,bmb1,b2,…,bm,表示每个特殊关卡的编号。

输出格式

一个整数,表示挑战者通过所有关卡获得的总分数的最大可能值。

保证最终答案不超过 264−1264−1。

数据范围

前 44 个测试点满足 1≤n≤41≤n≤4。
所有测试点满足 1≤n,m≤1001≤n,m≤100,m≤min(n,30)m≤min(n,30),1≤ai≤1071≤ai≤107,1≤bi≤n1≤bi≤n,bibi 两两不同。

输入样例1:

4 1
1 3 7 5
3

输出样例1:

18

输入样例2:

3 2
10 3 8
2 3

输出样例2:

40

输入样例3:

2 2
100 200
1 2

输出样例3:

400

输入样例4:

1 1
1
1

输出样例4:

1
难度:中等
时/空限制:1s / 256MB
总通过数:975
总尝试数:3285
来源:AcWing,第83场周赛
算法标签

分析

这题其实是一个贪心题,就是先打非特殊关卡,特殊关卡从大到小排序后依次打。

代码

#include <iostream>
#include <algorithm>
#include <map>
#include <string>
#include <cstring>
#define ll long long
using namespace std;
const int mod=1e9+9;
const int N=100010;
ll a[N];
bool st[106];
int main(){
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	} 
	for(int i=1;i<=n;i++){
		int id;
		cin>>id;
		st[id]=1;
	}
	int cnt=0;
	ll ans=0;
	int b[110];
	for(int i=1;i<=n;i++){
		if(!st[i]){
			ans+=a[i];
		}
		else{
			b[++cnt]=a[i];
		}
	}
	sort(b+1,b+cnt+1);
	reverse(b+1,b+cnt+1);
	for(int i=1;i<=cnt;i++){
		if(ans>b[i]){
			ans*=2ll;
		}
		else ans+=b[i];
	} 
	cout<<ans<<endl;
	return 0;
	
}

QAQ!