【题解】CF413C Jeopardy!

\(\color{blue}{Link}\)

\(\text{Solution:}\)

首先,显然的策略是把一定不能翻倍的先加进来。继续考虑下一步操作。

考虑\(x,y\)两个可以翻倍的物品,且\(a_x>a_y.\)

那么,设原来答案为\(sum\),则有下面情况:

先选择\(x:\)

  • \(a_x<sum\)则翻倍,与此同时\(a_y\)也必定小于\(sum.\)
  • \(a_x>sum\)\(sum\to sum+a_x\)与此同时\(a_y<sum.\)

先选择\(y:\)

  • \(a_y<sum\)则翻倍,\(a_x\)待定。
  • \(a_y>sum\)\(sum\to sum+a_y\),\(a_x\)待定。

但对比上面的选法,先选\(a_y\)与先选\(a_x\)的一些情况无异,反而,如果加了\(a_x\)再翻倍和加了\(a_y\)翻倍显然\(a_x\)更优。于是我们推出先选择\(a_x.\)

由此,证毕,此题得解。

\(\text{Q.E.D.}\)

#include<bits/stdc++.h>
using namespace std;
int n,a[500010],b[500010],m;
int mx,sum,vis[500010];
inline bool cmp(int x,int y){return a[x]>a[y];}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)scanf("%d",&a[i]);
	for(int i=1;i<=m;++i)scanf("%d",&b[i]),vis[b[i]]=1;
	if(n==m){
		for(int i=1;i<=n;++i)mx=mx<a[i]?a[i]:mx;
		cout<<(mx<<(n-1))<<endl;
		return 0;
	}
	sort(b+1,b+m+1,cmp);
	for(int i=1;i<=n;++i)sum+=(!vis[i]?1:0)*a[i];
	for(int i=1;i<=m;++i){
		if(a[b[i]]>=sum)sum+=a[b[i]];
		else sum=sum+sum;
	}
	cout<<sum<<endl;
	return 0;
}
posted @ 2020-06-15 19:39  Refined_heart  阅读(163)  评论(0编辑  收藏  举报