UVA 11729

来源:互联网 发布:资海网络集团电话 编辑:程序博客网 时间:2024/06/08 18:35

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
原创粉丝点击