Problem 1085 Work Reduction.
题意
- rounding down - 四舍五入
- 计算每个小帮手帮你完成任务的最小花费
- 输入:
case数
N初始文件数,M目标文件数(就是你要完成N-M的文件),L你的小帮手数量
(1 <= M <= N <= 100000, 1 <= L <= 100)
“[agency name]:A,B”,名字在1-16个字符,全是大写字母
A表示完成一个文件的单价
B表示完成你目前剩下的所有文件的一半的费用
- 输出非降序排列
思路
- 结构体help,分别记录name、A、B和cost
- 对目前的文件总数num:
①选择B方案处理的文件数四舍五入:deal = (int)(n/2.0+0.5)
②如果num-M>=deal(要处理的比总的一半多)且B比A划算 :cost = cost+B、num = num - deal
否则将剩余num-M个文件全部按A处理,break输出结果
(易知每经过一次处理num的数量一定减少,则B方案的单价一定是递增的)
笔记
- rounding down - 四舍五入
- 整数除2四舍五入:(int)(n/2.0+0.5)
- 字符串结束符记得加
\0
strcmp(a, b)
字符串比大小不能直接用大小于,字符可以
代码
#include<cstdio>
#include<algorithm>
#include<string.h>
using namespace std;
struct Help{
char name[20];
int A, B;
int cost;
}help[110];
bool cmp(Help a, Help b){
if(a.cost!=b.cost)
return a.cost<b.cost;
else
return strcmp(a.name, b.name)<0;
}
int main(){
int count, N, M, L;
int num, deal;
scanf("%d", &count);
for(int i=1; i<=count; i++){
scanf("%d%d%d", &N, &M, &L);
getchar();
for(int j=0; j<L; j++){
num = N;
int len=0;
char c;
scanf("%c", &c);
while(c!=':'){
help[j].name[len++] = c;
scanf("%c", &c);
}
help[j].name[len++] = '\0';
scanf("%d,%d", &help[j].A, &help[j].B);
getchar();
help[j].cost = 0;
while(1){
deal = (int)(num/2.0+0.5);
if((num-M>=deal) && (help[j].B < help[j].A*deal)){
help[j].cost += help[j].B;
num -= deal;
}else{
help[j].cost += (num-M)*help[j].A;
break;
}
}
}
printf("Case %d\n", i);
sort(help, help+L, cmp);
for(int j=0; j<L; j++)
printf("%s %d\n", help[j].name, help[j].cost);
}
return 0;
}