三种解法(dp,两种贪心)

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

有 N 份 homework ,每份有 deadLine 和 score,如果超过deadLine 还没做完,该homework的 score 将被扣去,做完每份homework的时间是相等的,为一天。求扣分最少的策略的扣分数。

解法一:动态规划

与  毕业bg 这题有诸多类似之处,代码也与之雷同,但不同的是,这道题中的 homework 的cost 是1,从而能用贪心优化(如果是>1的即使它们都相等也不能用贪心优化)

#pragma warning (disable:4786)  
#include<iostream>
#include<algorithm>
using namespace std;
#define MAX 1000
int  dp[MAX+10];
struct homeWork{
    int deadLine;
    int score;
};
homeWork ho[MAX+10];
int cmp( homeWork h1, homeWork h2 ){
    return h1.deadLine < h2.deadLine;
}
int main(){
    int t,n,i,j,sum;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        sum=0;
        for( i = 0; i < n; i ++ )
            scanf("%d",&ho[i].deadLine);
        for( i = 0; i < n; i ++ ){
            scanf("%d",&ho[i].score);
            sum += ho[i].score;            
        }
		//按 deadLine 升序排列
        sort( ho, ho + n, cmp );
		//dp数组中每一项设置为n个homework的score和
        for( i = 0; i <= ho[n-1].deadLine; i ++)
            dp[i] = sum;
        for( i = 0; i < n; i ++){
            for( j = ho[i].deadLine; j >= 1; j -- ){
                if( dp[j-1] - ho[i].score < dp[j] )
                    dp[j] = dp[j-1] - ho[i].score;
            }
        }
        int min = sum;
        for( i = 1; i <= ho[n-1].deadLine; i ++){
            if( dp[i] < min )
                min = dp[i];
        }
        printf("%d\n",min);
    }
}
解法二:贪心;将 homework 按 score 降序排列,同时用一个 size 为总天数的数组 time[ ] 记录每一天被使用的情况。对 homework 数组由前向后扫描,若 该homework的 deadLine 这天已被使用,则向前扫描 time 直到扫描到未被使用的一天,若扫描到头都没有符合条件的,则这一homework只能被放弃,扣去它的score。

解法三:贪心;将 homework 按 deadLine 升序排列,由后往前扫描 天数 数组,每一天的安排如下贪心:选择deadLine不在这一天之前的还没被安排的最大 score 的homework ,将这一 homework 在这天完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值