现在的位置: 首页 > 综合 > 正文

uva 10817 – Headmaster’s Headache(01背包)

2013年12月06日 ⁄ 综合 ⁄ 共 1733字 ⁄ 字号 评论关闭

题目链接:10817 - Headmaster's Headache

题目大意:某个学校要师资力量不够,要招收新的老师,第一行给出s、m、n,现在在任的老师有m个,然后给出m行表示每个老师的信息,分别是该老师的工资,以及可教授的课程(个数不一定),然后在n行表示可招收的老师信息,同样是工资和课程,s表示该学校开售的课程,问,最少花多少钱可以使得该学校开设的s个课程每个课程有两个老师任教。


解题思路:其实就是一个背包的问题,对于每个应聘的老师来说只有录取与不录取两种情况,以课程的任课老师数为背包的容量,起始位置为现任老师的任课情况,结束位置就为每个课程的任课老师数为两个,然后是背包容量的压缩,需要注意的是任课老师数大于2时按2个算。


#include <stdio.h>
#include <string.h>
#define min(a,b) (a)<(b)?(a):(b)
const int S = 10;
const int N = 105;
const int M = 25;
const int T = 8000;

struct teacher {
	int val;
	int cnt;
	int cas[S];
	teacher () {
		val = 0;
		cnt = 0;
		memset(cas, 0, sizeof(cas));
	}
}work[M], app[N];;
int s, n, m, dp[T]; 
int begin, end;

teacher read() {
	teacher now;
	char str[N];
	gets(str);
	int len = strlen(str), sum = 0;
	for (int i = 0; i <= len; i++) {
		if (str[i] >= '0' && str[i] <= '9')
			sum = sum * 10 + str[i] - '0';
		else {
			now.cas[now.cnt++] = sum;
			sum = 0;
		}
	}
	now.val = now.cas[0];
	return now;
}

void init() {
	memset(work, 0, sizeof(work));
	memset(app, 0, sizeof(app));
	for (int i = 0; i < m; i++) 
		work[i] = read();
	for (int i = 0; i < n; i++)
		app[i] = read();
}

int hash(int rec[]) {
	int sum = 0;
	for (int i = 1; i <= s; i++) {
		if (rec[i] > 2) rec[i] = 2;
		sum = sum * 3 + rec[i];
	}
	return sum;
}

void change(int rec[], int cur) {
	memset(rec, 0, sizeof(rec));
	for (int i = s; i > 0; i--) {
		rec[i] = cur % 3;
		cur /= 3;
	}
}

int handle() {
	int rec[S], sum = 0;
	memset(rec, 0, sizeof(rec));
	memset(dp, -1, sizeof(dp));
	for (int i = 0; i < m; i++) {
		sum += work[i].val;
		for (int j = 1; j < work[i].cnt; j++)
			rec[work[i].cas[j]]++;
	}
	begin = hash(rec);
	for (int i = 1; i <= s; i++)
		rec[i] = 2;
	end = hash(rec);
	return sum;
}

int solve() {
	int rec[S];
	int sum = handle();
	dp[begin] = sum;
	for (int i = 0; i < n; i++) {
		for (int j = end; j >= begin; j--) {
			if (dp[j] >= 0) {
				change(rec, j);
				for (int k = 1; k < app[i].cnt; k++)
					rec[app[i].cas[k]]++;
				int t = hash(rec);
				if (dp[t] == -1)
					dp[t] = dp[j] + app[i].val;
				else
					dp[t] = min(dp[t], dp[j] + app[i].val);
			}
		}
	}
	return dp[end];
}

int main() {
	while (scanf("%d%d%d", &s, &m, &n), s || n || m) {
		char str[N];
		gets(str);
		init();
		printf("%d\n", solve());
	}
	return 0;
}

抱歉!评论已关闭.