题意
给出一个长度为NNN的不下降序列,以及CCC,求出从这序列中取数使得最大且不超过CCC。
思路
从后往前搜索,枚举选不选,再加上一点剪枝就能过掉了。
正解是折半搜索,如果直接暴力搜索,那么时间复杂度为O(2n)O(2^n)O(2n),这里NNN最大是404040,我们可以把它分成两半,做两次搜索,那么最大时间复杂度就为O(2∗220)O(2*2^{20})O(2∗220),然后二分一下答案就可以过掉了。
代码
#include<cstdio>
#include<algorithm>
int n, c, ans;
int a[41];
long long pre[41];
void dfs(int p, long long sum) {
if (sum > c) return;
if (sum + pre[p - 1] <= c) {//前面的都可以取完
ans = std::max((long long)ans, sum + pre[p - 1]);
return;
}
ans = std::max((long long)ans, sum);
for (int i = p - 1; i >= 1; i--)
dfs(i, sum + a[i]);
}
int main() {
scanf("%d %d", &n, &c);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (int i = 1; i <= n; i++)
pre[i] = pre[i - 1] + a[i];
dfs(n + 1, 0);
printf("%d", ans);
}
本文介绍了一种使用折半搜索算法解决特定问题的方法,即在不下降序列中找到最大值,使其不超过给定限制。通过将序列分为两半并进行搜索,再结合二分查找,可以有效地降低时间复杂度。

被折叠的 条评论
为什么被折叠?



