您的位置:首页 > 其它

UVA 10817 - Headmaster's Headache(dp记忆化搜索)

2013-10-28 21:25 411 查看
The headmaster of Spring Field School is considering employing some new teachers for certain subjects. There are a number of teachers applying for the posts. Each teacher
is able to teach one or more subjects. The headmaster wants to select applicants so that each subject is taught by at least two teachers, and the overall cost is minimized.


Input

The input consists of several test cases. The format of each of them is explained below:
The first line contains three positive integers SM and NS (≤ 8) is the number of subjects, M (≤
20) is the number of serving teachers, and N (≤ 100) is the number of applicants.
Each of the following M lines describes a serving teacher. It first gives the cost of employing him/her (10000 ≤ C ≤ 50000), followed by a list of subjects
that he/she can teach. The subjects are numbered from 1 to S.You must keep on employing all of them. After that there are N lines, giving the details of the applicants in the same format.
Input is terminated by a null case where S = 0. This case should not be processed.

Output

For each test case, give the minimum cost to employ the teachers under the constraints.

Sample Input

2 2 2
10000 1
20000 2
30000 1 2
40000 1 2
0 0 0


Sample Output

60000

题意:给定s门课,m个教师和,n个兼职教师,m个教师必须全部雇佣,n个兼职教师可以选一些,然后保证每门课都至少有2个教师教,求最少付钱

思路:记忆化搜索,记录状态为dp[i][j],表示前i个教师达到j状态,这里j状态要进行一个状态压缩。

代码:

#include <stdio.h>
#include <string.h>

int min(int a, int b) {return a < b ? a : b;}
int s, m, n, v, ans, dp[105][10005], vis[105][10005], save;
int les[8];
char t[105];

struct Tea {
int v;
int les[8];
} tea[105];

int hash(int *a) {
int num = 0;
for (int i = 7; i >= 0; i --) {
num = num * 3 + a[i];
}
return num;
}

int dfs(int start, int *a) {
int x = hash(a);
if (vis[start][x]) return dp[start][x];
int &ans = dp[start][x];
ans = 999999999;
if (save == x)
ans = 0;
for (int i = start; i < n; i ++) {
int less[8];
for (int j = 0; j < 8; j ++) {
less[j] = a[j] + tea[i].les[j];
if (less[j] > 2) less[j] = 2;
}
if (hash(less) != hash(a))
ans = min(ans, dfs(i + 1, less) + tea[i].v);
}
vis[start][x] = 1;
return ans;
}

int main() {
while (~scanf("%d%d%d", &s, &m, &n) && s) {
ans = 0;
save = 0;
for (int i = s - 1; i >= 0; i --) {
save = save * 3 + 2;
}
memset(les, 0, sizeof(les));
memset(vis, 0, sizeof(vis));
memset(dp, 0, sizeof(dp));
memset(tea, 0, sizeof(tea));
for (int i = 0; i < m; i ++) {
scanf("%d", &v);
ans += v;
getchar();
gets(t);
for (int i = 0; i < strlen(t); i ++) {
if (t[i] >= '0' && t[i] <= '9' && les[t[i] - '0' - 1] < 2)
les[t[i] - '0' - 1] ++;
}
}
for (int i = 0; i < n; i ++) {
scanf("%d", &tea[i].v);
getchar();
gets(t);
for (int j = 0; j < strlen(t); j ++) {
if (t[j] >= '0' && t[j] <= '9' && tea[i].les[t[j] - '0' - 1] < 2)
tea[i].les[t[j] - '0' - 1] ++;
}
}
printf("%d\n", dfs(0, les) + ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: