zoukankan      html  css  js  c++  java
  • POJ:3616-Milking Time

    Milking Time

    Time Limit: 1000MS Memory Limit: 65536K
    Total Submissions: 12324 Accepted: 5221

    Description

    Bessie is such a hard-working cow. In fact, she is so focused on maximizing her productivity that she decides to schedule her next N (1 ≤ N ≤ 1,000,000) hours (conveniently labeled 0..N-1) so that she produces as much milk as possible.

    Farmer John has a list of M (1 ≤ M ≤ 1,000) possibly overlapping intervals in which he is available for milking. Each interval i has a starting hour (0 ≤ starting_houri ≤ N), an ending hour (starting_houri < ending_houri ≤ N), and a corresponding efficiency (1 ≤ efficiencyi ≤ 1,000,000) which indicates how many gallons of milk that he can get out of Bessie in that interval. Farmer John starts and stops milking at the beginning of the starting hour and ending hour, respectively. When being milked, Bessie must be milked through an entire interval.

    Even Bessie has her limitations, though. After being milked during any interval, she must rest R (1 ≤ R ≤ N) hours before she can start milking again. Given Farmer Johns list of intervals, determine the maximum amount of milk that Bessie can produce in the N hours.

    Input

    • Line 1: Three space-separated integers: N, M, and R
    • Lines 2..M+1: Line i+1 describes FJ’s ith milking interval withthree space-separated integers: starting_houri , ending_houri , and efficiencyi

    Output

    • Line 1: The maximum number of gallons of milk that Bessie can product in the N hours

    Sample Input

    12 4 2
    1 2 8
    10 12 19
    3 6 24
    7 10 31

    Sample Output

    43


    解题心得:

    1. 题意就是有m头牛,每一只牛有一个产奶的时间段和一个奶量,Bessie可以去给每一头奶牛挤奶,但是每次给一个奶牛挤奶之后必须休息R分钟,问Bessie选择怎么挤奶可以使挤出的奶最多。
    2. 最直观的的方法还是记忆化搜索,不用去推状态转移方程式,直接跟着题意走就行了。但是如果要推状态转移方程式就有很多种方法了,看过其他大佬最简单的方法就是按照每一只牛的时间段来转移,dp[i]表示按开始产奶的时间顺序处理第i头牛可以获得的最大的产奶量,转移方程可以从前面j头牛(如果第j头牛的时间符合)+第i头牛产的奶来更新dp[i]的最大值。其实这个状态转移就讲记忆化搜索提炼出来的公式,具体的看代码吧。

    记忆化搜索的代码:

    #include <algorithm>
    #include <cstring>
    #include <stdio.h>
    using namespace std;
    const int maxn = 1010;
    int n,m,R;
    
    struct COW {
        int l,r,va;
    }cow[maxn];
    
    long long dp[maxn*maxn];
    
    bool cmp(COW a, COW b) {
        return a.l < b.l;
    }
    
    void init() {
        memset(dp,-1,sizeof(dp));
        scanf("%d%d%d",&n,&m,&R);
        for(int i=0;i<m;i++) {
            scanf("%d%d%d",&cow[i].l,&cow[i].r,&cow[i].va);
        }
        sort(cow,cow+m,cmp);
    }
    
    long long dfs(int num,int Time) {
        long long k0 = 0,k1 = 0;
        if(num >= m || Time >= n)
            return 0;
        if(dp[Time] != -1 && Time != -1)
            return dp[Time];
        if(cow[num].l >= Time && cow[num].r <= n) { //如果时间符合那就加上当前这头牛的产奶量
            k1 += dfs(num+1,cow[num].r+R) + cow[num].va;
        } else
            k1 += dfs(num+1,Time);//时间不符合直接检查下一头
        k0 += dfs(num+1,Time);
        return dp[Time] = max(k0,k1);
    }
    
    int main() {
        init();
        long long ans = dfs(0,-1);
        printf("%lld
    ",ans);
        return 0;
    }

    提炼出状态转移的公式之后的代码:

    #include <algorithm>
    #include <stdio.h>
    using namespace std;
    const int maxn = 1010;
    struct COW {
        int start_time,end_time,va;
    
        bool operator < (const COW &A) const {
            return A.start_time > start_time;
        }
    }cow[maxn];
    
    int dp[maxn];
    
    int main() {
        int n,m,R;
        scanf("%d%d%d",&n,&m,&R);
        for(int i=1;i<=m;i++) {
            scanf("%d%d%d",&cow[i].start_time,&cow[i].end_time,&cow[i].va);
            cow[i].end_time += R;//实际结束的时间 = 结束时间 + 休息时间
        }
    
        sort(cow+1,cow+m+1);
    
        for(int i=1;i<=m;i++) {
            dp[i] = cow[i].va;
            for(int j=1;j<i;j++) {
                if(cow[j].end_time <= cow[i].start_time)
                    dp[i] = max(dp[i],dp[j] + cow[i].va);
            }
        }
    
        int ans = 0;
        for(int i=0;i<=m;i++)
            ans = max(ans,dp[i]);
        printf("%d
    ",ans);
    
        return 0;
    }
  • 相关阅读:
    1、Elasticsearch教程-从入门到精通
    3、ik分词器
    2、ElasticSearch的安装
    svn操作
    2020-10
    编写第一个linux驱动
    字符设备驱动
    Linux下/dev和/sys/class的区别
    latex
    Qt
  • 原文地址:https://www.cnblogs.com/GoldenFingers/p/9107115.html
Copyright © 2011-2022 走看看