Codeforces 888E - Maximum Subsequence 折半枚举
2018-01-15 21:37
211 查看
888E -
Maximum Subsequence
题意:
给出了N个数和M,要在N个数中任意找出k个数,令这k个数的和mod M的值最大。(N<=35,M<=1e9)
分析:
用到了 meet-in-the-middle 的思想,能极大的优化
DFS 的暴力。数字的个数N最大只有35。但是直接暴力需要2^35显然不可以,我们可以分别暴力
左右n/2个数,丢到两个set中,遍历第一个set,再对第二个进行二分查找。这样复杂度就从O(2^n)降到O(log(N/2)*2^(N/2))
在二分过程中,如何取小于等于一个数的数呢(lower_bound or upper_bound都无法完成这中操作)。这里看到别人的做法大有收益,
就是首先将标等于upper_bound(),这样就取到了一个大于所求数的数,再将标自减(例:it--)就可以取到小于等于所求值的最大值了。
Maximum Subsequence
题意:
给出了N个数和M,要在N个数中任意找出k个数,令这k个数的和mod M的值最大。(N<=35,M<=1e9)
分析:
用到了 meet-in-the-middle 的思想,能极大的优化
DFS 的暴力。数字的个数N最大只有35。但是直接暴力需要2^35显然不可以,我们可以分别暴力
左右n/2个数,丢到两个set中,遍历第一个set,再对第二个进行二分查找。这样复杂度就从O(2^n)降到O(log(N/2)*2^(N/2))
在二分过程中,如何取小于等于一个数的数呢(lower_bound or upper_bound都无法完成这中操作)。这里看到别人的做法大有收益,
就是首先将标等于upper_bound(),这样就取到了一个大于所求数的数,再将标自减(例:it--)就可以取到小于等于所求值的最大值了。
#include<bits/stdc++.h> using namespace std; const int MAX_N = 1e3 + 9; set<int> st[2]; int vec[MAX_N]; int N,M,T; void dfs(int val,int l,int r) { if(l == r) { st[r == N].insert(val); return; } dfs((val+vec[l])%M,l+1,r); dfs(val,l+1,r); } int main() { while(cin>>N>>M) { st[0].clear(); st[1].clear(); for(int i=0;i<N;i++) { cin>>vec[i]; vec[i] = vec[i]%M; } dfs(0,0,N/2); dfs(0,N/2,N); set<int>::iterator it,pos; int ans = 0; for(it = st[0].begin();it!=st[0].end();it++) { int t = *it; int x = M - t - 1; pos= st[1].upper_bound(x); //这里找到大于所求的数后将标向后移,恰好是小于等于所求数的标! pos--; ans = max(*pos+t,ans); } cout<<ans<<endl; } return 0; }
相关文章推荐
- [Codeforces 585D] Lizard Era: Beginning (折半枚举)
- codeforces 888E Maximum Subsequence (折半枚举 双向搜索)
- codeforces 429B Working out (四方向dp枚举交点)
- POJ - 2549 Sumsets(折半枚举)
- poj 2785 4 Values whose Sum is 0 折半枚举
- poj2549 Sumsets(折半枚举)
- POJ 3977:Subset(折半枚举+二分)
- 2017年第0届浙江工业大学之江学院程序设计竞赛决赛 Problem E: qwb和李主席(折半搜索+类二分枚举)
- poj3977Subset (折半枚举)
- CodeForces - 618C Constellation 枚举
- HDU 5936 Difference 折半枚举,暴力
- Codeforces 888E(位运算+meet-in-the-middle)
- CodeForces 543B Destroying Roads(最短路 + 枚举)
- Codeforces 626D Jerry's Protest(暴力枚举+概率)
- CodeForces 379D 暴力 枚举
- CodeForces 552D — Vanya and Triangles 暴力枚举
- CodeForces 558C Amr and Chemistry (位运算,数论,规律,枚举)
- Codeforces Round #456 (Div. 2): E. Prime Gift(折半枚举)
- 4 Values whose Sum is 0 (POJ-2785) (折半枚举)
- POJ 2785 4 Values whose Sum is 0(折半枚举)