2.最大费用
2.最大费用
题面
题目描述
商场一共 \(n\) 个物品,第 \(i\) 件物品的价格为 \(a_i\),每件物品只能买一件,你手上有 \(m\) 块钱。
求最多支出多少钱。
输入格式
第一行两个整数 \(n,m\)。
接下来 \(n\) 个整数,表示 \(a_i\)。
输出格式
输出最多支出是多少钱。
样例
样例 1 输入
3 10
1 2 3
样例 1 输出
6
样例 2 输入
4 10
4 3 5 11
样例 2 输出
9
数据范围与提示
对于 \(10\%\) 的数据,\(n\leq 10\)。
对于 \(30\%\) 的数据,\(n\leq 20\)。
对于 \(60\%\) 的数据,\(n\leq 30\)。
对于 \(100\%\) 的数据,\(1\leq n\leq 40\)。
分析
- 第一眼,Dp?
- 第二眼,m多大?哦,原来没给
- 那么 \(40\) 个数全部遍历找支出,需要 \(40!\) 次。
- 那么折半搜索登场了
- 将 \(n\) 个数分成两份,一份 \(1\sim \lfloor \frac{n}{2} \rfloor\),另一份 \(\lfloor \frac{n}{2} \rfloor + 1 \sim n\)。
- 将两份中小于或等于 \(m\) 的情况全部用数组存起来。
- 然后通过两份的各自一种情况相加,来得到小于等于 \(m\) 的最大值(如果不选那么那一份的情况为 \(0\))。
- 最后,\(m\) 多大?
- 不知道?那么开个 long long 不过分吧,毕竟也没有明示用高精。
Code
#include <bits/stdc++.h>
using namespace std;
const int N = 50;
long long n, m;
long long a[N], ans;
vector<long long> l, r;
void dfs(int st, int en, long long sum, vector<long long> &now) {
if (sum > m) return;
if (st > en) {
now.push_back(sum);
return;
}
dfs(st + 1, en, sum + a[st], now);
dfs(st + 1, en, sum, now);
}
int main (void) {
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
}
dfs(1, (n >> 1), 0, l);
dfs((n >> 1) + 1, n, 0, r);
sort(l.begin(), l.end());
sort(r.begin(), r.end());
int lr = r.size();
for (int i = 0; i < lr; ++i) {
int p = lower_bound(l.begin(), l.end(), m - r[i] + 1) - l.begin() - 1;
if (p > 0) ans = max(ans, l[p] + r[i]);
}
cout << ans;
return 0;
}