UVA 11729

Uva 11729

这道题本可以用贪心去做的,但是我这里就没有贪心

我的思路这样的,先安排那几个手下人以每个人的执行任务的时间长度从大到小排好序,这样做是为了让尽量多的人在分配任务的时候尽量就去开始执行任务了,这样也是为了更加省时,然后用dp[i]代表检索到第i个人,给第i个人分配完任务之后,还需要dp[i]的时间才能使得所有已经被分配任务的人完成所有被分配的任务。

来个例子,就比如第二个样例,

5 5

4 4

3 3

这组样例里边,先按照这样的顺序排好,就是上边的顺序,

然后给第一个人分配任务,在分配完之后,还需要5小时才能够让他完成,

再然后给第二个人分配任务(花了4小时),在分配完之后,还需要4个小时才能够使得这两个人都完成任务,怎么算的?

先看下,在这第一个人分配完任务之后还要5个小时才能够使得第一个人完成任务,你会发现,第一个人在执行任务到第4个小时的时候,第二个人已经被分配任务了,这个时候,第一个人还要一个小时才能够完成他的任务,而第二个人才刚刚开始执行任务,他还需要4小时才能够完成他的任务,所以就是在这个时候dp[1]=4,注意这里的i从0开始的,这里的1代表的其实是第二个人的dp,依次类推。。。

总结下,怎么算的,就是如果检索到第i个人的话,要求dp[i],那么就必须先求刚给第i个人分配完任务,这个时候前边的人执行任务到了什么程度,也就是说前边的那些人还需要多久(用t表示)才能够完成他们的任务,然后拿起这个时间和第i个人的执行任务去比较大小,取较大的,就是这个dp[i]了,现在怎么求这个t怎么求呢?就是当dp[i-1]大于这个第i个人的分配任务的时候,就取dp[i-1]-第i个人的分配任务的时间,如果小于的话,那么就是0了,当然如果你还是取dp[i-1]-第i个人的分配任务的时间的话,那么也是可以的,因为这个值已经是个负的了,然后再和第i个人的执行任务的时间(正值)去比较大小,取大的,最后也没有影响!!!

最后结果就是dp[n-1]+所有人的执行任务的时间之和。

下边就看下我的代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
struct Node{
int f,z;
} a[10005];
bool compare(const Node a,const Node b){
    return a.z==b.z?a.f>b.f:a.z>b.z;
}
int dp[10005];
int n;
int f(int a,int b){
    if(a<b)return 0;
    return a-b;
}
int main()
{
    int time=1;
//    freopen("F:\\cb代码文件\\input.txt", "r", stdin);
    while(~scanf("%d",&n)){
            if(!n)break;
            int sum=0;
        for(int i=0;i<n;i++){
                scanf("%d%d",&a[i].f,&a[i].z);
                sum+=a[i].f;
            }
            sort(a,a+n,compare);
            dp[0]=a[0].z;
            a[n].f=0;
            for(int i=1;i<n;i++)
            {
                int t=f(dp[i-1],a[i].f);
                dp[i]=max(t,a[i].z);
            }
           printf("Case %d: %d\n",time++,sum+dp[n-1]);
    }
}
//3
//5 5
//4 4
//3 3
就这些了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值