0
点赞
收藏
分享

微信扫一扫

洛谷P4799 [CEOI2015 Day2]世界冰球锦标赛 题解 折半搜索+二分

题目链接:​​https://www.luogu.com.cn/problem/P4799​​

解题思路:
如果暴搜时间复杂度是 \(O(2^{40})\),所以考虑折半搜索。

前一半搜索的时候记录好所有的状态,然后对这些状态对应的价格排序。

后一半搜索的时候到边界条件时用二分确定前一半的数量。

时间复杂度降到 \(O(2^{20} \cdot 20 \cdot 2)\)。

示例代码如下:

#include <bits/stdc++.h>
using namespace std;
int n;
long long m, a[44], b[1<<21], cnt, ans;
void dfs1(int id, long long tmp) {
if (tmp > m) return;
if (id > n/2) {
b[cnt++] = tmp;
return;
}
dfs1(id+1, tmp);
dfs1(id+1, tmp+a[id]);
}
void dfs2(int id, long long tmp) {
if (tmp > m) return;
if (id > n) {
int p = upper_bound(b, b+cnt, m-tmp) - b;
ans += p;
return;
}
dfs2(id+1, tmp);
dfs2(id+1, tmp+a[id]);
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i ++) cin >> a[i];
dfs1(1, 0);
sort(b, b+cnt);
dfs2(n/2+1, 0);
cout << ans << endl;
return 0;
}


举报

相关推荐

0 条评论