uva 11729
分类: 贪心
题意: 每个人分派任务,分配和完工需要时间,如何安排分配顺序总完工时间最小
输入: 任务数N,每个人分配需要的时间B,每个人执行需要的时间J
输出: 总完成最快时间、
解法:贪心
核心:
①两个任务交换顺序不会影响其它任务的最终完成时间
②那么何种情况下交换两种任务可以减少总时间
分两种情况
情况一:交换之前前面的任务后结束 J[1] >= J[2] + B[2]
[B...1][J...........1]
[B.2][J.2]
B[1]+J[1]是总时间且 > B[2]+B[1]+J[2]
如果交换
交换后完成总时间是
B[2]+B[1]+J[1] 可以看到总时间变长了,所以不交换
情况二:交换之前前面的任务先结束 有 J[1] < B[2] + J[2]
B[...1][J....1]
B[...2][J...2]
交换前的总时间是B[1] + B[2] + J[2]
再分两种情况:
①交换之后 1先结束 有 J[2] > B[1] + J[1] 总时间变短了
②交换之后 2先结束 有 J[2] < B[1] + J[1] 总时间为 B[2] + J[1] + B[1] 要使得总时间变短需要 J[1] < J[2]
以上是贪心的依据
#include <iostream> #include <vector> #include <map> #include <list> #include <set> #include <deque> #include <stack> #include <queue> #include <algorithm> #include <cmath> #include <cctype> #include <cstdio> #include <iomanip> #include <cmath> #include <cstdio> #include <iostream> #include <string> #include <sstream> #include <cstring> #include <queue> using namespace std; ///宏定义 const int INF = 990000000; const int MAXN = 2010; const int maxn = MAXN; ///全局变量 和 函数 int N; struct task { int B; int J; int finishTime; bool operator < (const task& t) const { return J > t.J; } }; task Task[maxn]; int main() { ///变量定义 int cases = 1; while (scanf("%d", &N) && N) { for (int i = 0; i < N; i++) { task tempTask; scanf("%d%d", &tempTask.B, &tempTask.J); Task[i] = tempTask; } sort(Task, Task + N); int disTime = 0; for (int i = 0; i < N; i++) { Task[i].finishTime = disTime + Task[i].B + Task[i].J; disTime += Task[i].B; } int ans = Task[0].finishTime; for (int i = 0; i < N; i++) { if (Task[i].finishTime > ans) ans = Task[i].finishTime; } printf("Case %d: %d\n", cases++, ans); } ///结束 return 0; }