HDU 5188 · zhx and contest【01背包】【约束条件】

【题意】

作为史上最大的刷子,zhx经常要参加各种比赛。
一天,zhx参加比赛,他发现这个比赛对他来说异常的容易。
比赛有n个问题,他知道他解决在 ti 时间单位 ith 问题能得到 vi 分。
他叼爆了,主办方一直盯着他。若他在 li 时间前解决了 ith 问题,他会被认为是作弊。
zhx真的不想把这些无聊的问题做完。他只想得不少于 w 分。
你应该告诉告诉他在不认为是作弊的情况下,他所需用最小时间,或者他得不到足够的分。
注意,zhx同一时间只能解决一个问题。并且如果他开始,他将一直做到问题解决。然后他会立即提交他的代码。
限制条件:
1n30
0w109
1ti,li105
1vi109

【提炼】

zhx只能在 li 时间后(包含 li )花 ti 时间完成 ith 问题得到 vi 分,求他怎么花最少的时间得到 w 分。

【分析】

因为zhx只能在 li 时间后(包含 li )做完 ith 问题,不妨认为他做完 ith 问题,然后等到 li 时间才开始做下一道。

思路:
将所需等待时间小的先完成( = );
也就是说我们将用尽可能少的时间(这个时间是总时间)内得到尽可能多的分;
也就是说我们将尽可能地先完成规定时间靠前的题来得到尽可能快地得到目标分 w

这里做个思维转化,将每道题的分数看成价值,每道题的只能在 li 时间后(包含 li )解决看成花费空间,这样我们就把它转换成了一个带有约束条件的Zero-One-Pack。

约束条件:
一方面,是等待时间要尽可能小(可能为负数),并且最后空间花费不能低于 li
另一方面,在遍历最小空间花费时,不能让数组内的下标为负数,即 jti0

【时间复杂度】

sum=i=0n1ti

这取决于 sum 的大小,因为要为了找到最大值不管是求的时候还是最后遍历一遍, sum=max{sum,maxl} ,所以,时间复杂度为
O(sum)

【代码】

/*
    coder:  Tangent Chang
    date:   2017/5/14
    I have nothing to offer but blood, boil, tears and sweat.  by Winston Churchill
*/

#include 
#include 
#include 
#include 
#include 

using namespace std;

typedef long long ll;

const int maxn  = 1000005;

struct node {
    int t, v, l;

};

bool cmp(node a, node b) {
    return a.l - a.t < b.l - b.t;
}

ll max1(ll a, ll b) {
    return a > b ? a : b;
}

node s[50];
int n, w;
ll sum, maxl, d[maxn];

int main() {
    while (~scanf("%d%d", &n, &w)) {
        sum = 0;
        maxl = 0;
        memset(d, 0, sizeof(d));
        for (int i = 0; i < n; ++i) {
            scanf("%d%d%d", &s[i].t, &s[i].v, &s[i].l);
            sum += s[i].t;
            maxl = max1(maxl, s[i].l);
        }
        sort(s, s + n, cmp);
        sum = max1(sum, maxl);
        for (int i = 0; i < n; ++i) {
            for (ll j = sum; j >= s[i].l; j--) {
                if (j >= s[i].t) {
                    d[j] = max1(d[j], d[j - s[i].t] + s[i].v);
                }
            }
        }
        int res;
        bool flag  = 0;
        for (res = 0; res <= sum; ++res) {
            if (d[res] >= (ll)w) {
                flag = 1;
                break;
            }
        }
        if (!flag) {
            printf("zhx is naive!\n");
        }
        else {
            printf("%d\n", res);
        }
    }
    return 0;
}

你可能感兴趣的:(背包问题)