POJ 3172 Scales (01背包暴力)

题意:给定 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
", 0);
        return 0;
    }
    int cnt = 0;
    for(int i = n-1; i >= 0; --i){
        if(a[i] == m){
            printf("%d
", m);
            return 0;
        }
        else if(a[i] < m){
            cnt = i;
            break;
        }
    }
    ans = (1<<30)+5;
    dfs(cnt, m);

    printf("%d
", m - ans);
    return 0;
}
原文地址:https://www.cnblogs.com/dwtfukgv/p/5716166.html