赞
踩
https://codeforces.com/contest/1610/problem/C
题意:有n个人,富裕程度1~n, 要举行派对,要求对于每个人,来的人中比他富的不超过
a
i
a_i
ai, 比他穷的不超过
b
i
b_i
bi,问最多能邀请多少人来.
思路:二分答案,把答案最大化。关键是怎么统计能邀请多少人,假设可以邀请mid人,对于每个人,记录当前已经邀请了cnt人,如果
b
i
b_i
bi>=cnt,并且
a
i
a_i
ai>=mid-cnt-1, 那么说明可以邀请这个人。
code :
#include<bits/stdc++.h> using namespace std; #define endl '\n' #define ios std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); //head const int N=2e5+10; int a[N],b[N]; int n; bool check(int mid)//mid为答案选几个 { int cnt=0;//当前选了cnt个 for(int i=1;i<=n;i++){ if(b[i]>=cnt&&a[i]>=mid-cnt-1) cnt++; } if(cnt>=mid) return 1; return 0; } void solve() { cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]>>b[i]; } int l=1,r=n; while(l<r) { int mid=l+r+1>>1; if(check(mid)) l=mid; else r=mid-1; } cout<<r<<endl; } signed main() { ios; int t; cin>>t; //t=1; while(t--) { solve(); } return 0; }
题目大意:给定一个序列 a ,a为未知序列,长度为n,给m个已知信息,为从 a l a_l al 到 a r a_r ar 的或的值为x, 求a的所有子集中元素异或值的和。
思路:对二进制下每一位分析,就比如对于每个元素的第3位,构成一个集合b,b={b1,b2,b3,…bn}, 对于某个 b i b_i bi, 若 b i b_i bi 为1,则将集合分为含有 b i b_i bi和不含 b i b_i bi的两种集合,其数量均为 2 n − 1 2^{n-1} 2n−1个,其异或值为1的一定在这两个集合的其中一个,因此每一位1的贡献为 :当前1对应的值 * 2 n − 1 2^{n-1} 2n−1, 那么怎么判断当前位是否有1呢?直接将所有x或起来即可。
code:
#include<bits/stdc++.h> using namespace std; #define endl '\n' #define ios std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define int long long //head typedef pair<int,int> pii; const int N=2e5+10,mod=1e9+7; int qmi(int a,int k) { int ans=1; while(k) { if(k&1) ans=(ans*a)%mod; a=(a*a)%mod; k>>=1; } return ans; } void solve() { int n,m; cin>>n>>m; int ans=0; while(m--) { int l,r,x; cin>>l>>r>>x; ans|=x; } cout<<ans*qmi(2,n-1)%mod<<endl; } signed main() { ios; int t; cin>>t; while(t--) { solve(); } return 0; }
题目大意 : 将长度为n的序列a,(初始全为1),最多经过k次变化,能获得的最大值是多少。每次变化操作为: a i a_i ai+= a i a_i ai/x;将 a i a_i ai 变为 b i b_i bi 可以获得 c i c_i ci 的值。
思路:01背包求解,预处理出来每个 a i a_i ai 变为 b i b_i bi 的最小次数, 以该次数为体积,以 c i c_i ci 为价值做一遍01背包即可。需要注意的是每个数最大变化次数不超过12次,而k值较大,因此在求体积时要与k取 min。
code:
#include<bits/stdc++.h> using namespace std; #define endl '\n' #define ios std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); //head const int N=1e5+10; int b[N],w[N],v[N]; int n,k; int f[N],cnt[100010]; void solve() { memset(f,0,sizeof f); cin>>n>>k; int sum=0; for(int i=1;i<=n;i++) cin>>b[i]; for(int i=1;i<=n;i++) cin>>w[i]; for(int i=1;i<=n;i++) { v[i]=cnt[b[i]]; sum+=v[i]; } k=min(k,sum); for(int i=1;i<=n;i++){ for(int j=k;j>=v[i];j--){ f[j]=max(f[j-v[i]]+w[i],f[j]); } } cout<<f[k]<<endl; } signed main() { memset(cnt,0x3f,sizeof cnt); cnt[1]=0; for(int i=1;i<=1e3;i++){ for(int j=1;j<=i;j++){ cnt[i+(i/j)]=min(cnt[i+(i/j)],cnt[i]+1); } } //ios; int t; cin>>t; //t=1; while(t--) { solve(); } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。