10670 Work Reduction (贪心 + 被题意坑了- -)y
Problem C: Work Reduction
Paperwork is beginning to pile up on your desk, and tensions at the workplace are starting to mount. Your boss has threatened to fire you if you don't make any progress by the end of the day. You currently have N units of 易做图work on your desk, and your boss demands that you have exactly M units of 易做图work left by the end of the day.
The only hope for you now is to hire help. There are various agencies which offer 易做图work reduction plans:
For $A they will reduce your 易做图work by one unit.
For $B they will reduce your entire 易做图work by half (rounding down when necessary).
Note that work can never be reduced to less than 0.
Your task now is to produce a sorted table of agency names and their respective minimum costs to solve your workload problem.
The first line of input consists of a single positive integer representing the number of cases to follow. Each case begins with three positive integers separated by spaces: N - your starting workload, M - your target workload, and L - the number of work reduction agencies available to you, (1 <= M <= N <= 100000, 1 <= L <= 100). The next L lines have the format "[agency name]:A,B", where A and B are the rates as described above for the given agency. (0 <= A,B <= 10000) The length of the agency name will be between 1 and 16, and will consist only of capital letters. Agency names will be unique.
For each test case, print "Case X", with X being the case number, on a single line, followed by the table of agency names and their respective minimum costs, sorted in non-decreasing order of minimum costs. Sort job agencies with identical minimum costs in alphabetical order by agency name. For each line of the table, print out the agency name, followed by a space, followed by the minimum required cost for that agency to solve your problem.
Sample Input
2
100 5 3
A:1,10
B:2,5
C:3,1
1123 1122 5
B:50,300
A:1,1000
C:10,10
D:1,50
E:0,0
Sample Output
Case 1
C 7
B 22
A 37
Case 2
E 0
A 1
D 1
C 10
B 50
题意:有n个任务,要求完成到m个。。现在有l家公司,每家公司有一个名字有A代表完成一项工作花A元,B代表完成一半的工作花B元。。。对于这个完成一半。题目中是说rounding down。。我开始以为是向下取整。结果答案跑出来都跟样例不一样。。后来才明白其实是四舍五入。。。还有题目中公司的名字是字符串。我一开始看样例想当然以为是一个字符。结果WA了几次。。。。。哎
还有一个注意点。输出要按花费少的排序。就是如果花费相同,就按名字的字典序排序。
思路:贪心。。每次比较一件件完成和完成一半谁花得少。就用哪个方案。直到n / 2 >= m 为止。。剩下还没完成的部分。只能一项项完成(因为最后剩下的任务一定要是m)。。
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; int t, n, m, l; struct Work { char name[20]; int a, b; int value; } w[105]; int cmp(Work aa, Work bb) { if (aa.value != bb.value) return aa.value < bb.value; if (strcmp(aa.name, bb.name) < 0) return 1; else return 0; } void solve(int nn) { int num = n; while (num / 2 >= m) { if (w[nn].b < (num -num / 2) * w[nn].a) w[nn].value += w[nn].b; else w[nn].value += w[nn].a * (num - num / 2); num /= 2; } w[nn].value += (num - m) * w[nn].a; } int main() { int Case = 1; scanf("%d", &t); while (t --) { memset(w, 0, sizeof(w)); scanf("%d%d%d%*c", &n, &m, &l); for (int i = 0; i < l; i ++) { char sb; int j = 0; while ((sb = getchar()) != EOF && sb != ':') { w[i].name[j ++] = sb; } w[i].name[j] = '\0'; scanf("%d%*c%d%*c", &w[i].a, &w[i].b); } for (int i = 0; i < l; i ++) { solve(i); } sort(w, w + l, cmp); printf("Case %d\n", Case ++); for (int i = 0; i < l; i ++) printf("%s %d\n", w[i].name, w[i].value); } return 0; }
补充:软件开发 , C++ ,