CF413C Jeopardy!

CF413C Jeopardy!

洛谷传送门

题意翻译

题意简述

“Jeopardy!”的决赛将有n问题,每个问题都有对应的得分ai,其中有m个问题可以选择不得分,而将现有总得分翻倍。你可以安排关卡的通过顺序和策略,求最大得分。

输入输出格式

输入格式:

第一行包含两个整数。n和m(1<=n,m<=100;m<=min(n,30))分别代表问题总数和可翻倍问题总数。第二行包含n个整数a1,a2,...,an(1<=ai<=1e7)代表每个问题的价值;第三行包含m个整数b1,b2,...,bm(1<=bi<=n)代表可翻倍问题的编号。问题编号是从1到n。

输出格式:

一行一个数字,表示通过所有关卡最大得分。保证该答案在64位带符号整型范围内。

感谢@Peter_Matthew 提供的翻译


题解:

贪心题。

对于那些不能翻倍的直接加一起。

对于能翻倍的,肯定要考虑翻不翻倍对答案的贡献哪个大。

那么,发现大的翻倍肯定更大,所以在排序的过程中,把所有能翻倍的按权值从大到小排序。然后从大到小依次判断到底要不要翻倍。这样的决策一定是最优的。

所以这题在考结构体排序

代码:

#include<bits/stdc++.h>
using namespace std;
int n, m;
long long ans;
struct node
{
	int val;
	bool f;
	bool operator < (const node &a) const {
		return f < a.f || (f == a.f && val > a.val);
	} 
}a[220];
int main() 
{
	scanf("%d%d",&n,&m);
	for (int i = 1; i <= n; ++i) 
        cin >> a[i].val, a[i].f = 0;
	for (int i = 1; i <= m; ++i) 
    {
		int x;
		scanf("%d", &x);
		a[x].f = 1;
	}
	sort(a + 1, a + n + 1);
	for (int i = 1; i <= n; ++i) 
    {
		if (!a[i].f)
			ans = ans + a[i].val;
        else
        {
			if (ans > a[i].val) ans *= 2;
			else ans = ans + a[i].val;
		}
	}
	printf("%lld\n",ans);
    return 0;
}
posted @ 2020-11-20 18:54  Seaway-Fu  阅读(97)  评论(0编辑  收藏  举报