题目描述
某综艺频道推出了一个闯关活动。
活动一共包含 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 两两不同。
代码
#include <stdio.h>
int main () {
long result = 0;
int n,m;
scanf ("%d %d",&n,&m);
int score[100],temp,special_score[100];
for (int i = 0;i < n;i++) {
scanf ("%d",&score[i]);
}
for (int i = 0;i < m;i++) {
scanf ("%d",&temp);
special_score[i] = score[temp-1];
score[temp-1] = 0;
}
for (int i = 0;i < n;i++) {
result += score[i];
}
for (int i = 0;i < m-1;i++) {
for (int j = 0;j < m -1- i;j++) {
if (special_score[j] < special_score[j+1] && m != 1) {
int t = special_score[j];
special_score[j] = special_score[j+1];
special_score[j+1] = t;
}
}
}
for (int i = 0;i < m;i++) {
if (result > special_score[i]) {
result *= 2;
}
else {
result += special_score[i];
}
}
printf ("%ld",result);
}