首页 > 代码库 > uva:10670 - Work Reduction(贪心)

uva:10670 - Work Reduction(贪心)

题目:10670 - Work Reduction


题目大意:给出n, m, L.n代表老板给的全部的paperworks的数量,m代表最终剩下的数量,L代表由这么多家公司需要你来计算最小的花费。

解题思路:

1、L家公司l行。每行由公司的名字 :A,B; A代表一份paperwork需要的money,B则代表帮你减少到总共的paperworks的数量一半要话费的money。注意这里是你手头上有的paperworks而不是老板要求你完成的数量,之前在这里卡了好久。还有减半不能导致最终的数量小于m。因为老板要求的是一定要剩下m份。

2、把输入的字符串分离出名字和钱A, B。

3、计算出金额排序输出。

代码:

#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;

const int N = 105;
int n, m, l;
struct MONEY {

	char name[N];
	int money;
	int a, b;
} M[N];
char str[N];

int cmp (const MONEY & x, const MONEY & y) {

	if (x.money < y.money)
		return true;
	else if (x.money > y.money)
		return false;
	else return strcmp (x.name, y.name) < 0 ? true: false;
}
//分离字符串 分离出名字和费用
void handle (int j) {
	
	int k = 0;
	for (int i = 0; i < strlen (str); i++) {

		if (str[i] != ':')
			k++;
		else
			break;	
	}
	memcpy (M[j].name, str, sizeof (str));
	M[j].name[k] = '\0';
	
	int sum = 0;
	for (int i = k + 1; i < strlen (str); i++) {

		if (str[i] != ',')
			sum = sum * 10 + str[i] - '0';
		else {
			
			M[j].a = sum;
			sum = 0;
		}
	}
	M[j].b = sum;	
}
//计算费用
void cal (int j) {

	int num = n;
	int sum = 0;
	while (1) {

		if (num / 2 >= m && (num - num / 2 ) * M[j].a >= M[j].b)	{
			
			sum += M[j].b;
			num /= 2;
		} else {
			
			sum += (num - m) * M[j].a;
			M[j].money = sum;
			break;
		}
	}
}

int main () {
	
	int t;
	char ch;
	scanf ("%d", &t);
	for (int i = 1; i <= t; i++) {

		printf ("Case %d\n", i);
		scanf ("%d%d%d%c", &n, &m, &l, &ch);
		for (int j = 0; j < l ; j++) {

			gets(str);
			handle(j);
			cal(j);
		}
		sort (M, M + l, cmp);
		
		for (int j = 0; j < l ; j++)
			printf ("%s %d\n", M[j].name, M[j].money);
	}
	return 0;
}