Codeforces 480D Parcels(dp)

179 篇文章 0 订阅
163 篇文章 3 订阅

题目链接:Codeforces 480D Parcels

题目大意:就是有一个用来堆放货物的板,承重力为S。现在有N件货物,每件货物有到达的时间,运走的时间,以及

重量,承重,存放盈利。如果这件货物能再运达时间存放,并在指定时间取走的话,就能获得相应的盈利值。货物都是

逐个往上叠的,每个箱子上面的总重量不能大于箱子的承重。总的质量不能大于板的承重,货物上面还有货物的话是不

能被取走的。现在求最大的盈利值。

解题思路:dp好题,没想出来,看懂别人代码A掉的。

首先将货物按照运走时间早的,运进时间晚的排序,贪心的思想,越早处理掉越早把钱赚了。然后dp[i][j]表示说装入第i

个货物,并且当前重量为j的最大收益。

类似与逆思想的方式,从先移动出去的货物开始考虑,然后向后转移,因为会有说in3,in1,out1,in2,out2,out3这

样的情况,即货物1和货物2的重量是不需要叠加的,两个钱都赚的话也不会影响到货物3,所以f[i]数组用来维护说在i时

刻前已经移走的货物净赚最大值。在考虑第i个货物的时候,需要判断前面i-1个货物,只有在in_i ≤ in_j && out_j ≤ out_i

的时候,才能转移,转移的过程中一并维护f数组。

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 500;
struct Parcel {
    int in, out, w, s, v;
    void read() {
        scanf("%d%d%d%d%d", &in, &out, &w, &s, &v);
    }
}p[maxn];

inline bool cmp (const Parcel& a, const Parcel& b) {
    return a.out < b.out || (a.out == b.out && a.in > b.in);
}

int N, S, dp[maxn + 5][maxn * 2 + 5], f[maxn * 2 + 5];

int main () {
    scanf("%d%d", &N, &S);
    p[0] = (Parcel){0, 2 * maxn, 0, S, 0};
    for (int i = 1; i <= N; i++)
        p[i].read();
    sort(p, p + N + 1, cmp);

    for (int i = 0; i <= N; i++) {
        for (int w = p[i].w; w <= S; w++) {
            int o = p[i].in;
            int wi = min(p[i].s, w - p[i].w);
            f[o] = 0;

            for (int j = 0; j < i; j++) if (p[j].in >= p[i].in) {
                while (o < p[j].out) {
                    o++;
                    f[o] = f[o-1];
                }
                f[o] = max(f[o], f[p[j].in] + dp[j][wi]);
            }
            dp[i][w] = f[o] + p[i].v;
        }
    }

    printf("%d\n", dp[N][S]);
    return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值