您的位置:首页 > 其它

UVA—10817 Headmaster's Headache

2015-12-10 19:42 274 查看
紫书上面的最优匹配问题,

讲解是有问题的,所以很仔细地研习了这【篇博客.

点击打开链接

完全不会看,一看像是01背包问题,悲催地忘记01背包问题了。基础太不扎实了。

所以重新复习第9章的例题迫在眉睫,定在星期6.

UVA10817-这个看LRJ的代码看懂了。

但是学不会。有点烦。

还是基础太差了。

所以。还是要多做。踏实。

解析:

将所有课程二进制压缩。

然后st[maxn]表示将每个老师所教的课程压缩

d[maxn][1<<maxs][1<<maxs]表示

1维表示前i个人。

2维表示只有1个人教的课程

3维表示至少有2个人教的课程。

m个在职教师编号为0到m-1

n个求职者编号为m到m+n-1

对于教师 不存在不选的情况

在选的情况中。

注意 没人教的课程,有1个人教的课程。有2个人教的课程之间的变化即可.

附上LRJ的代码。

// UVa10817 Headmaster's Headache
// Rujia Liu
#include<cstdio>
#include<cstring>
#include<iostream>
#include<sstream>
using namespace std;

const int maxn = 100 + 20 + 5;
const int maxs = 8;
const int INF = 1000000000;
int m, n, s, c[maxn], st[maxn], d[maxn][1<<maxs][1<<maxs];

// s1是一个人教的科目集合,s2是两个人教的科目集合
int dp(int i, int s0, int s1, int s2) {
if(i == m+n) return s2 == (1<<s) - 1 ? 0 : INF;
int& ans = d[i][s1][s2];
if(ans >= 0) return ans;

ans = INF;
if(i >= m) ans = dp(i+1, s0, s1, s2); // 不选

// 选
int m0 = st[i] & s0, m1 = st[i] & s1;//m0表示第i个人教的课程中没人教的,m1表示第i个人教的课程中有1个人教的
s0 ^= m0;//s0中去掉m0;
s1 = (s1 ^ m1) | m0;//s1中去掉m1并且加上m0
s2 |= m1;//s2中加上m1
ans = min(ans, c[i] + dp(i+1, s0, s1, s2));
return ans;
}

int main() {
int x;
string line;
while(getline(cin, line)) {
stringstream ss(line);
ss >> s >> m >> n;
if(s == 0) break;

for(int i = 0; i < m+n; i++) {
getline(cin, line);
stringstream ss(line);
ss >> c[i];
st[i] = 0;
while(ss >> x) st[i] |= (1 << (x-1));//二进制存储,为0实则2^0=1;
}
memset(d, -1, sizeof(d));
cout << dp(0, (1<<s)-1, 0, 0) << "\n";
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: