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 ;
}