一、题目
二、解法
由于两队都要最有策略,所以只有最大的 个是有用的,看到数据范围只有 ,可以状压。
那么进入了喜闻乐见的 环节,如果是 操作的话自己选一定比随机选更优,不进行 操作相当于禁用战斗力最小的一个,所以没影响。设 为已选择的状压为 的最大差值 最小差值(要看轮到的是谁),然后枚举哪一个被操作即可。
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int M = 105;
const int inf = 0x3f3f3f3f;
int read()
{
int x=0,f=1;char c;
while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
int n,m,a[M],b[M],c[M],d[1<<20],dp[1<<20];char s[5];
signed main()
{
n=read();
for(int i=1;i<=n;i++)
a[i]=read();
m=read();
sort(a+1,a+1+n,greater<int>());
for(int i=1;i<=m;i++)
{
scanf("%s",s);c[i]=read();
if(s[0]=='p') b[i]=1;
else b[i]=2;
}
for(int i=1;i<(1<<m);i++)
{
d[i]=d[i>>1]+(i&1);
int j=m-d[i]+1;
if(c[j]==1) dp[i]=-inf;
else dp[i]=inf;
for(int k=0;k<m;k++)
{
if(!(i&(1<<k))) continue;
int l=(b[j]==1?a[k+1]:0);
if(c[j]==1) dp[i]=max(dp[i],dp[i^(1<<k)]+l);
else dp[i]=min(dp[i],dp[i^(1<<k)]-l);
}
}
printf("%d\n",dp[(1<<m)-1]);
}