题意:给你一个不降序序列(序列长度N),然后让你求能够组成的最大的不超过c的值是多少
一开始想的是价值和重量相等的01背包问题,但是发现c的范围是有符号整数([-2^{31},2^{31}-1])
改用暴力,基本方法是二进制枚举,但是需要一些剪枝:
- 如果中间发现sum > c 就return
- 如果发现sum + s[u] (s为w的前缀和)满足 <= c 就更新ans = max(ans, sum + s[u]) 并return
- 如果发现sum + s[u] 满足 <= ans 直接return 没必要再做了
另外的话,题目中的每个砝码的质量至少等于前面两个砝码(也就是质量比它小的砝码中质量最大的两个)的质量的和。假设砝码序列为a,并且a[0], a[1] 取非零数字中最小的1,并且a[i] = a[i 1] + a[i - 2]那么a为斐波那契序列,由于斐波那契序列在第47项时>(2^{31}-1),所以题目中的(N < 47)
#include<iostream>
using namespace std;
const int N = 1010;
#define int long long
int w[N], s[N];
int n, c;
int ans;
void dfs(int u, int sum){
if(sum > c) return;
if(sum + s[u] <= ans) return;
if(sum + s[u] <= c){
ans = max(ans, sum + s[u]);
return;
}
if(u == -1){
ans = max(sum, ans);
return;
}
dfs(u - 1, sum);
dfs(u - 1, sum + w[u]);
}
signed main(){
cin >> n >> c;
for(int i = 1; i <= n; i ++) cin >> w[i];
for(int i = 1; i <= n; i ++) s[i] = w[i] + s[i - 1];
dfs(n, 0);
cout << ans << endl;
return 0;
}