uva 10817 - Headmaster's Headache(01背包)

来源:互联网 发布:我的凉山兄弟 知乎 编辑:程序博客网 时间:2024/06/05 17:09

题目链接: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;elsedp[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;}