经典贪心算法uva11729
uva11729
这个题的题意是
你有n个部下,每个部下需要完成一项任务。第i个部下需要你花Bi分钟交代任务,然后他会立刻独立地、无间断地执行Ji分钟后完成任务。
你需要选择交待任务的顺序,使得所有任务尽早执行完毕(即最后一个执行完的任务应尽早结束)。注意,不能同时给两个部下交待任务,
但部下们可以同时执行他们各自的任务
求完成所有任务的最短时间
实际上呢我们知道这是一个排序的问题。。当然有时候可以转化成其他问题。。
我们先按它是一个排序的问题来搞一下。。
那么每个元素就有两个属性交待的时间a,完成任务的时间b,显然这是一个二维偏序的问题(?)
那么我们考虑第一维有三种情况(等于,大于,小于),第二维也有三种情况。。
由组合数学的乘法原理得。。最后的结果总数是3*3=9
那么我们枚举小数据来看看相邻两个元素怎么放置可以使结果最小,如果这个确定的话那么我们可以冒泡排序
通过交换来维持这个性质,当然这个是要有前提的,那就是要满足最优子结构的性质,也就是说这个问题呢
要满足如果我序列里任何相邻元素都满足上面使结果最小的顺序导致我总体结果也是最小的那么这样的话,
应该是满足最优子结构的性质的,那么我们分析这个问题。。很显然你把它两两相邻考虑
从一个元素开始慢慢往上加。。每加入一个元素我们就调整顺序。。那么这样我们就保证了使每次取max(pre-element,cur-element)
我们每次使这个将要考虑的cur-element最小,那么我们最后取得最大值就会最小。。
那么如果我们用探索法画图画这九种情况来分析规律
我们画了5种。。但是足以看出来。。我们先做执行任务长的,时间会更短
那么我们其实还发现不管什么顺序。。安排任务的时间总和是固定的。。但是结果不同
区别就在于分配任务的前缀和加上哪个执行任务时间对答案的贡献。。那么我们显然可以得到。。执行任务时间最长的应该配
一个较短的分配任务前缀和。。这样可以减小这个最大值对答案的贡献
还有一些地方不太懂。。再做几道类似的题目再说吧
UVA的64位整数是%lld 另外要注意答案输出格式。。不要以为数值对了就能AC。。
贴上AC代码
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int maxn=1e3+7; int N; struct node{ int a,b; }Node[maxn]; bool cmp(node a,node b){ if(a.b!=b.b) return a.b>b.b; else return a.a>b.a; } int main(){ int cnt=0; while(~scanf("%d",&N)){ if(N==0) break; int i,j; for(i=0;i<N;++i){ scanf("%d%d",&Node[i].a,&Node[i].b); } sort(Node,Node+N,cmp); ll previd1=Node[0].a; ll mx=previd1+Node[0].b; for(i=1;i<N;++i){ previd1+=Node[i].a; mx=max(mx,previd1+Node[i].b); } printf("Case %d: %lld\n",++cnt,mx); } return 0; }