uva 10670 Work Reduction(贪心)

该博客主要介绍了UVA 10670道题目的解决方法,题目涉及的工作量优化问题需要在一定条件下减少工作量,并考虑公司提供的两种服务。解题策略采用贪心算法,通过比较每家公司每单位工作量的费用,选择最优服务。最终目标是使剩余工作量达到特定值,同时输出各公司单独完成任务的最小费用,按费用升序排列,费用相同则按公司名称字典序排序。

题目连接:10670 - Work Reduction


题目大意:有tol的工作量,和要求达到的工作剩余量sur,然后是公司总数,对应每个公司提供两种服务,1、完成一个工作量,2.完成当前未完成工作量的一半(注意这里是tol的一半,不是tol - sur的一半), 当剩余工作量为奇数, 对模2四舍五入。现在给出每个公司的两种服务所需费用, 要求计算出每个公司单独完成工作量所花费的最少金额(剩余工作量必须为sur,输出按照金额大小,相同按照公司名字的字典序大小。


解题思路:贪心, 对于每个公司,比较当前单位工作量的花费金额,来决定选用哪种服务。


#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = 105;

struct company {
    char name[N];
    int one;
    int half;
    int value;
}tmp[N];
char str[N];
int tol, sur;

bool cmp(const company &a, const company &b) {
    if (a.value < b.value)  return true;
    else if (a.value > b.value)	return false;
    else
	return strcmp(a.name, b.name) < 0;
}

int count(int t, int h) {
    int sum = tol, cur = 0;
    while (sum != sur) {
	int w = (sum + 1) / 2;
	if (t * w > h && sum - w >= sur) {
	    sum -= w;
	    cur += h;
	}
	else {
	    sum--;
	    cur += t;
	}
    }
    return cur;
}

void handle(int cur) {
    int len = strlen(str), cnt = 0, sex = 0;
    for (int i = 0; i < len; i++) {
	if (sex == 0 && str[i] != ':')
	    tmp[cur].name[cnt++] = str[i];
	else if (str[i] == ':') {
	    tmp[cur].name[cnt++] = '\0';
	    sex++;
	}
	else if (sex == 1 && str[i] != ',')
	    tmp[cur].one = tmp[cur].one * 10 + str[i] - '0';
	else if (str[i] == ',')
	    sex++;
	else
	    tmp[cur].half = tmp[cur].half * 10 + str[i] - '0';
    }
    tmp[cur].value = count(tmp[cur].one, tmp[cur].half);
}

int main() {
    int cas, t = 1, n;
    scanf("%d", &cas);
    while (cas--)  {
	memset(tmp, 0, sizeof(tmp));
	scanf("%d%d%d%*c", &tol, &sur, &n);
	for (int i = 0; i < n; i++) {
	    gets(str);
	    handle(i);
	}

	sort(tmp, tmp + n, cmp);

	printf("Case %d\n", t++);
	for (int i = 0; i < n; i++)
	    printf("%s %d\n", tmp[i].name, tmp[i].value);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值