hdu 1789

来源:互联网 发布:淘宝的solidworks 编辑:程序博客网 时间:2024/05/28 16:00

题目大意:有一些作业规定了完成日期,如果没有在规定的日期完成就会就会扣掉期末的成绩,一天只能够完成一门作业,现在Ignatius想尽可能的减少所扣的成绩。 

题目分析:说好的动态规划专题为什么有贪心;  其实很简单的一个贪心啦:(but刚看到题目没有想出来); 主要原因大脑中没有这种贪心模型。。。

 试想一下,如果只能选择一些课,放弃一些课,你会怎么选择; 当然是完成扣份大的课,这样才能够让结果最优;但是有时间限制了应该怎么办呢,我们还是应该尽可能的优先完成扣份大的课,这样如果起冲突,也是放弃扣份小的课;  那么优先扣份大的课应该怎么选才能让结果最优呢? 如果截止时间是x,我们可以选择在第一天完成,也可以直到x天完成,应该在哪一天呢。看例子吧

   A 3, 5; (表示课程a的作业,时间期限是第三天,如果没有完成扣5分), 同理 (B 1,1);这两门课,如果我们希望优先完成A,但是如果A放在了第一天,会导致B扣份,但是很明显我们如果先做在第2天做A,第一天写B是可以一份不扣的;  这样时间选择就出来了,应该最少的占据别的课的时间;(选择放在最后的期限,如果依然对别的课时间产生了影响,这样的影响就是不可避免的;

  最优贪心出来了;

看代码,很简单的:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;// 这道题貌似是个贪心, 不开心:int n, used[1000+10];struct Node{    int v, t;}node[1000+10];bool cmp(const Node &a, const Node &b){    return a.v > b.v;}int main(){    int T;    scanf("%d", &T);    while(T--){        scanf("%d", &n);        for(int i = 0; i < n; ++i) scanf("%d", &node[i].t);        for(int i = 0; i < n; ++i) scanf("%d", &node[i].v);        sort(node, node+n, cmp);        // 贪心选择;        int ans = 0;        memset(used, 0, sizeof(used));        for(int i = 0; i < n; ++i){            int x = node[i].t;            for( ; x >= 1; --x) if(used[x] == 0) { used[x] = 1; break; }            if(x < 1) ans += node[i].v;        }        printf("%d\n", ans);    }    return 0;}

 

0 0