题意:给定 n 个数,保证下一个数比上一个数和前一个数之和大,然后给定一个背包,问你最多放多少容积。
析:应该是很明显的01背包,但是可惜的是,数组开不出来,那就得考虑暴力,因为数不多,才几十而已,要不然就超int了,然后我就暴力做了,超时了,
这个还是前剪枝的,这样剪的,先把前几项和算出来,确定最大砝码的重量,然后在暴力时,如果发现剩下的比总和还小,或者等于,就不用再算了,直接结束就好了,
这样做时间竟然是0毫秒,可能是标程吧,并不是很理解为什么是0.
代码如下:
#include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <iostream> #include <cstring> #include <set> #include <queue> #include <string> #include <algorithm> #include <vector> #include <map> using namespace std ; typedef long long LL; typedef pair<int, int> P; template<class T>T scan(T &x){ int f = 1; x = 0; char c; while(c = getchar(), c < 48) if(c == '-') f = -1; do x = x * 10 + (c^48); while(c = getchar(), c > 47); x *= f; return x; } const int INF = 0x3f3f3f3f; const double inf = 0x3f3f3f3f3f3f3f; const double eps = 1e-11; const int maxn = 50 + 5; const int dr[] = {0, 0, -1, 1}; const int dc[] = {-1, 1, 0, 0}; int a[maxn]; int n, m, ans; LL sum[maxn]; int Min(int a, int b){ return a < b ? a : b; } void dfs(int cur, int w){ if(w < 0) return ; if(!cur){ if(w >= a[cur]) w -= a[cur]; ans = Min(ans, w); return ; } if(w >= sum[cur]){ w -= sum[cur]; ans = Min(ans, w); return ; } dfs(cur-1, w); dfs(cur-1, w-a[cur]); } int main(){ scanf("%d %d", &n, &m); for(int i = 0; i < n; ++i){ scanf("%d", &a[i]); sum[i] = sum[i-1] + a[i]; } if(m < a[0]){ printf("%d\n", 0); return 0; } int cnt = 0; for(int i = n-1; i >= 0; --i){ if(a[i] == m){ printf("%d\n", m); return 0; } else if(a[i] < m){ cnt = i; break; } } ans = (1<<30)+5; dfs(cnt, m); printf("%d\n", m - ans); return 0; }