NC53424. Forsaken喜欢玩自走棋
描述
输入描述
第一行一个表示羁绊的数量。接下来行每行两个整数,代表在二进制下个限制代表的值,代表增幅值。
输出描述
两个整数,表示应该选哪个羁绊,表示最大的增幅值。
示例1
输入:
2 1 2 1 5
输出:
0 7
C++11(clang++ 3.9) 解法, 执行用时: 745ms, 内存消耗: 16024K, 提交时间: 2019-10-25 21:08:36
#include<bits/stdc++.h> using namespace std; long long t[1000005]; int s,v,y,n; long long d[1000005],ans=-1e18; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d %d",&s,&v); t[s]+=v; } for(int i=1;i<=1000000;i++){ if(t[i]==0) continue; for(int j=i;j;j=(j-1)&i){ d[j]+=t[i]; } d[0]+=t[i]; } for(int i=0;i<=1000000;i++){ if(ans<d[i]){ ans=d[i]; y=i; } } cout<<y<<" "<<ans<<endl; return 0; }
C++14(g++5.4) 解法, 执行用时: 187ms, 内存消耗: 10388K, 提交时间: 2019-10-30 18:15:16
#include<bits/stdc++.h> using namespace std; #define ll long long ll a[1<<20+5]; int main() { int n; cin>>n; for(int i=1;i<=n;i++) { ll x,y; cin>>x>>y; a[x]+=y; } for(int j=0;j<20;j++) for(int i=0;i<1<<20;i++) { if(i>>j&1) a[i^(1<<j)]+=a[i]; } ll ans=-1,idx=0; for(int i=0;i<1<<20;i++) { if(ans<a[i]) { ans=a[i],idx=i; } } cout<<idx<<' '<<ans<<endl; return 0; }