Codeforces Round #222 (Div. 1) C. Captains Mode

来源:互联网 发布:小米网络助手能删吗 编辑:程序博客网 时间:2024/06/01 09:45

首先注意到无论是选择,还是禁选英雄都会选能力强的英雄,事实上只要考虑前m强的英雄就可以了,这样英雄最多只有20个。

dp[i][st]表示操作第i步的人,在面对st这个状态时做多能赢对手多少,st是英雄的一个状态,表示当前可操作的英雄集合。转移的时候枚举选出那个英雄,以及考虑下下一步是自己操作还是对手操作就可以了。

#include <cstdio>#include <cstring>#include <algorithm>#define maxn 100009#define MOD 1000000007#define INF 1e9using namespace std;int a[maxn],n,m;int dp[25][1<<20];struct node{char s[5];int t;}p[30];bool cmp(int x,int y){return x>y;}int dfs(int i,int st){if(i==n+1)return 0;int &ans=dp[i][st];if(ans!=-INF)return ans;else{int inv=1;if(p[i].t!=p[i+1].t){inv=-1;}if(p[i].s[0]=='p'){for(int j=0;j<n;j++){if((st&(1<<j))==0){ans=max(ans,a[j]+inv*dfs(i+1,st^(1<<j)));}}}else{for(int j=0;j<n;j++){if((st&(1<<j))==0){ans=max(ans,inv*dfs(i+1,st^(1<<j)));}}}return ans;}}int main(){scanf("%d",&m);for(int i=0;i<m;i++)scanf("%d",&a[i]);sort(a,a+m,cmp);scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%s%d",p[i].s,&p[i].t);for(int i=0;i<=n+1;i++) for(int j=0;j<1<<n;j++) dp[i][j]=-INF;int ans=dfs(1,0);if(p[1].t==2)ans=-ans;printf("%d\n",ans);//system("pause");return 0;}


0 0
原创粉丝点击