• HDU1789 Doing Homework again 动态规划 Or 贪心


    http://acm.hdu.edu.cn/showproblem.php?pid=1789

    题义是给定一个作业序列,求如何分配使得得到的分数最多。设 dp[i][j] 代表截止到第i个作业,第j天所能够完成的最多分数。

    dp方程为:

    if (1<= j <= e[i].time)     dp[i][j] = max(dp[i-1][j], d[i-1][j-1]+e[i].score);

    if (e[i].time+1 <= j <= Last)    dp[i][j] = max(dp[i-1][j], dp[i][j-1]);

    代码如下:

    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #define MAXN 1005
    using namespace std;
    
    int N, sum, Last, dp[MAXN][MAXN];
    
    struct Node
    {
        int time;
        int score; 
    }e[MAXN];
    
    bool cmp(Node a, Node b)
    {
        if (a.time != b.time) {
            return a.time < b.time;
        }
        else {
            return b.score < a.score;
        }
    }
    
    int DP()
    {
        sort(e+1, e+1+N, cmp);
        for (int i = 1; i <= N; ++i) {
            for (int j = 1; j <= e[i].time; ++j) {
                dp[i][j] = max(dp[i-1][j], dp[i-1][j-1]+e[i].score);
            }
            for (int j = e[i].time+1; j <= Last; ++j) {
                dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
            }
        }
        return dp[N][Last];
    }
    
    void init()
    {
        for (int i = 1; i <= N; ++i) {
            for (int j = 1; j <= Last; ++j) {
                dp[i][j] = 0;
            }
        }
    }
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while (T--) {
            sum = Last = 0;
            scanf("%d", &N); 
            for (int i = 1; i <= N; ++i) {
                scanf("%d", &e[i].time);
                Last = max(Last, e[i].time);
            }
            for (int i = 1; i <= N; ++i) {
                scanf("%d", &e[i].score);
                sum += e[i].score;
            }
            init();
            printf("%d\n", sum - DP());
        }
        return 0;
    }

    还有一种思路是利用贪心来做,为什么可以应用贪心规则呢?因为在这个题中,得分高的任务和得分低的都只占用1天的时间,这一天给谁不是给啊,还不如给得分高的,并把这个任务安排在限定期的最后一天。

    代码如下:

    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #define MAXN 1005
    using namespace std;
    
    int N, sum, hash[MAXN];
    
    struct Node
    {
        int time, score;
    }e[MAXN];
    
    bool cmp(Node a, Node b)
    {
        if (a.score != b.score) {
            return a.score > b.score;
        }
        else {
            return a.time < b.time;  
        }
    }
    
    int Greedy()
    {
        int ct, total = 0;
        sort(e+1, e+1+N, cmp);
        for (int i = 1; i <= N; ++i) {
            ct = e[i].time;
            while (hash[ct]) {
                --ct;  // 无论如何都让这件工作做完
            }
            if (ct > 0) {
                total += e[i].score;
                hash[ct] = 1;
            }
        }
        return total;
    }
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while (T--) {
            sum = 0;
            memset(hash, 0, sizeof (hash));
            scanf("%d", &N);
            for (int i = 1; i <= N; ++i) {
                scanf("%d", &e[i].time);
            }    
            for (int i = 1; i <= N; ++i) {
                scanf("%d", &e[i].score);
                sum += e[i].score;
            }
            printf("%d\n", sum - Greedy());
        }
        return 0;
    }
  • 相关阅读:
    java页面请求跑批处理sql的有关问题
    Linux下一个检查跑批是否成功的Shell
    redhat Linux5 安装vsftp .
    LINUX FTP简单配置
    java代理机制
    详细解析Java中抽象类和接口的区别
    抽象类和接口的区别
    SVN与Git比较
    浅谈存储过程和触发器
    存储过程,触发器,函数 学习总结
  • 原文地址:https://www.cnblogs.com/Lyush/p/2479493.html
Copyright © 2020-2023  润新知