【CF1210B】Marcin and Training Camp(贪心)

题意:有n个人,60种技能点,如果第i个人会第j种技能a[i]的二进制表示的第j位就是1,第i个人的价值是b[i]

如果有若干种技能i会j不会,i就会鄙视j

求一种至少两个人的选人方案使得价值和最大,而且不存在一个人鄙视剩余所有人

n<=7000,1<=b[i]<=1e9

思路:显然如果有n个人,他们的技能树完全一致,且n>=2,这些人肯定全取,用map维护一下

取完之后考虑剩下的,如果剩余的之间不存在超集关系他们必定互相鄙视

贪心,能加就加

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 typedef unsigned int uint;
 5 typedef unsigned long long ull;
 6 typedef pair<int,int> PII;
 7 typedef pair<ll,ll> Pll;
 8 typedef vector<int> VI;
 9 typedef vector<PII> VII;
10 typedef pair<ll,int>P;
11 #define N  200010
12 #define M  200010
13 #define fi first
14 #define se second
15 #define MP make_pair
16 #define pi acos(-1)
17 #define mem(a,b) memset(a,b,sizeof(a))
18 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
19 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
20 #define lowbit(x) x&(-x)
21 #define Rand (rand()*(1<<16)+rand())
22 #define id(x) ((x)<=B?(x):m-n/(x)+1)
23 #define ls p<<1
24 #define rs p<<1|1
25  
26 const ll MOD=1e9+7,inv2=(MOD+1)/2;
27       double eps=1e-4;
28       int INF=1<<30;
29       ll inf=5e13;
30       int dx[4]={-1,1,0,0};
31       int dy[4]={0,0,-1,1};
32  
33 ll a[N],x1[N],x2[N];
34 int b[N],y1[N],y2[N];
35 map<ll,int> mp1;
36 map<ll,ll> mp2;
37  
38 int read()
39 {
40    int v=0,f=1;
41    char c=getchar();
42    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
43    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
44    return v*f;
45 }
46  
47 int main()
48 {
49     mp1.clear();
50     mp2.clear();
51     int n=read();
52     rep(i,1,n) scanf("%lld",&a[i]);
53     rep(i,1,n) b[i]=read();
54     rep(i,1,n)
55     {
56         mp1[a[i]]++;
57         mp2[a[i]]+=b[i];
58     }
59     ll ans=0,S=0;
60     int m=0;
61     rep(i,1,n)
62      if(mp1[a[i]]>=2)
63      {
64          ans+=mp2[a[i]];
65          mp1[a[i]]=0;
66          x1[++m]=a[i];
67      }
68     //printf("ans=%lld\n",ans);
69     rep(i,1,n)
70      if(mp1[a[i]])
71      {
72         int flag=0;
73         rep(j,1,m)
74         {
75             ll t1=a[i]^x1[j],t2=a[i]|x1[j];
76             if(t1&&t2!=x1[j]) continue;
77             flag=1; break;
78         }
79         if(flag)
80         {
81             ans+=b[i];
82             m++;
83             x1[m]=a[i];
84         }
85      }
86  
87     printf("%lld\n",ans);
88     return 0;
89 }

 

posted on 2019-09-24 21:00  myx12345  阅读(299)  评论(0编辑  收藏  举报

导航