POJ 3616 Milking Time

来源:互联网 发布:贵州大数据是什么 编辑:程序博客网 时间:2024/05/18 01:52

POJ 3616题目大意如下:

又是FJ和他的牛,FJ给牛指定了产奶时间段,每个时间段内,牛在不停的产奶,当这个时间段完结后,牛需要R时间休息。给出M个时间段,和指定的间隔休息时间,以及每个产奶时间段产奶数量,求产奶的最大值。

终于自己AC了一个dp,但是还是wrong了两次(不细心,把M当成了R)。简单dp的基本就是写出状态转移方程,dp数组对应0到第j段产奶时间短的最末时间,表示整个区间,因此对于考虑的第i段,和第j段有如下关系:

如果指定区间和参考段没有时间重叠那么就有dp[i] = dp[j] + Seg[i].efficient

当然如果此值比dp[i]小,那就不更新,即有:dp[i] = max(dp[i], dp[j] + Seg[i].efficient)

可能会想,这样做会把某些区间和参考段重合的情况忽视了,但是这样更新的另一个原因是:这些重合区间是包含之前区间情况的,而且由于dp是对应一个个时间段,所以如果后面重叠时间段实际的情况是不重叠时间段的话,实际这种情况就是不重叠时间段(之前已经有了)

代码如下:

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>using namespace std;typedef long long int LL;const int maxn = 1000;struct Milking {    int start, end;    int efficent;}Seg[maxn + 3];int N, M, R;LL dp[maxn + 3];bool camp(const Milking& lhs, const Milking& rhs) {    return lhs.start < rhs.start || (lhs.start == rhs.start && lhs.end < rhs.end);}void solve() {    LL ans = 0;    sort(Seg, Seg + M, camp);    for (int i = 0; i < M; i++) dp[i] = Seg[i].efficent;    for (int i = 0; i < M; i++) {        for (int j = 0; j < i; j++) {            if (Seg[j].end + R <= Seg[i].start)                dp[i] = max(dp[i], dp[j] + Seg[i].efficent);        }        ans = dp[i] > ans ? dp[i] : ans;    }    printf("%lld\n", ans);}int main(int argc, const char * argv[]) {    // insert code here...    scanf("%d %d %d", &N, &M, &R);    for (int i = 0; i < M; i++) scanf("%d %d %d", &Seg[i].start, &Seg[i].end, &Seg[i].efficent);    solve();    return 0;}

Accept 712K/32MS

0 0