zoukankan      html  css  js  c++  java
  • POJ

    Milking Time

    题目大意:

    给你m个时间段,每个时间段包括一个开始时间和一个结束时间,另外还有一个价值,现在要你在连续的n时间内找到互不相交区间间隔相差r且完整的区间,使得价值和最大,输出价值和。

    数据范围:

    1m1000,1n1000000,0startinghouri<endinghourin,1rn

    解题思路:

    这个题呢,有个值得注意的点,如果没有注意到这个点题目就很难(我不会),那么要看见了的话就比较简单可想了,就是要注意到开始时间和结束时间都小于n,我开始以为仅仅只是小于1e6而已,那么这个题n就没有什么用处了,也就是这个限制条件并没有什么用,迷惑而已。那么就可以这么想,在将开始时间按从小到大排序之后,dp[i]代表选第i个后最大价值,那么第i个可以由之前的dp[1~i-1]转移过来,满足条件就加入状态并维护一个最大值,所以状态转移方程就为:
    if(dp[j].r+r<=dp[i].l)dp[i]=max(dp[i],dp[j]+num[i].w).

    AC代码:

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    const int maxn = 1000;
    int dp[maxn + 5];
    struct NOOD {
        int l, r, w;
    }num[maxn + 5];
    int n, m, r, Max;
    bool cmp(NOOD x, NOOD y) {return x.l < y.l;}
    int main() {
        scanf("%d%d%d", &n, &m, &r);
        for(int i = 1; i <= m; i++)scanf("%d%d%d", &num[i].l , &num[i].r, &num[i].w);
        sort(num + 1, num + m + 1, cmp);
        for(int i = 1; i <= m; i++) {
            dp[i] = num[i].w;//要么前面一个不要,即从自己开始
            for(int j = 1; j < i; j++)//要么从之前的状态找一个最大的
                if(num[j].r + r <= num[i].l)
                    dp[i] = max(dp[i], dp[j] + num[i].w);
        }
        Max = 0;
        for(int i = 1; i <= m; i++)Max = max(Max, dp[i]);
        printf("%d
    ", Max);
        return 0;
    }
  • 相关阅读:
    linux内核中GNU C和标准C的区别
    linux内核中GNU C和标准C的区别
    Getting start with dbus in systemd (02)
    Getting start with dbus in systemd (01)
    Getting start with dbus in systemd (03)
    物理内存相关的三个数据结构
    数据类型对应字节数(32位,64位 int 占字节数)
    Linux kernel 内存
    共模电感的原理以及使用情况
    [原创]DC-DC输出端加电压会烧毁
  • 原文地址:https://www.cnblogs.com/TRDD/p/9813525.html
Copyright © 2011-2022 走看看