Codeforces Round #588 (Div. 2) D Marcin and Training Camp
起初感觉是dp题,,,但是仔细看了数据之后发现数据很小。。。。。。然后就感觉是个思路题。
思路:
若此人可选,则必须有人的a值与他相同,或者是在有相同值a的二进制当中,只有1处能取1。 举例说明吧
例如例子:
对于这种情况并非所有的1能同时取, 但还是遵从上一条规律。(只不过不存在传递性)
1 #include<iostream> 2 #include<queue> 3 #include<cstdlib> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 8 typedef long long ll; 9 const int MAXN=7010; 10 ll b[MAXN],n,ans,cnt; 11 ll res[MAXN][62]; 12 struct s{ 13 ll id,a,b; 14 }a[MAXN]; 15 bool cmp(const s&a,const s&b) 16 { 17 if (a.a!=b.a) 18 return a.a<b.a; 19 return a.id<b.id; 20 } 21 void check(ll tmp) 22 { 23 ll p=60; 24 while (tmp){ 25 res[cnt][p]=tmp&1; 26 p--; 27 tmp>>=1; 28 } 29 return ; 30 } 31 void check1(int i) 32 { 33 ll temp[62],p=60; 34 memset(temp,0,sizeof(temp)); 35 while (a[i].a){ 36 temp[p]=a[i].a&1; 37 p--; 38 a[i].a>>=1; 39 } 40 for (int j=1;j<=cnt;j++){ 41 bool flag=false; 42 for (int k=0;k<=60;k++){ 43 if (res[j][k]==0&&temp[k]==1){ 44 flag=true; 45 break; 46 } 47 } 48 if (flag==false){ 49 ans=ans+a[i].b; 50 break; 51 } 52 } 53 return ; 54 } 55 int main() 56 { 57 a[0].a=-1; 58 ans=cnt=0; 59 cin>>n; 60 for (int i=1;i<=n;i++){ 61 cin>>a[i].a; 62 a[i].id=i; 63 } 64 for (int i=1;i<=n;i++){ 65 cin>>a[i].b; 66 } 67 sort(a+1,a+n+1,cmp); 68 queue<ll>q; 69 while(!q.empty()) 70 q.pop(); 71 for (int i=2;i<=n;i++){ 72 if (a[i].a==a[i-1].a&&a[i-1].a!=a[i-2].a){ 73 q.push(a[i].a); 74 cnt++; 75 check(a[i].a); 76 } 77 } 78 for (int i=1;i<=n;i++){ 79 check1(i); 80 } 81 cout<<ans<<endl; 82 return 0; 83 }