您的位置:首页 > 其它

LightOJ - 1011 Marriage Ceremonies(状压DP)

2015-10-27 22:35 363 查看
题目大意:给你N对男女的匹配的值,问如果配对,才能使每个男女只有一个配偶,且配对的和最大

解题思路:这题用二分图的最大权比配也可以做

我这边用的是DP,因为最多只有16个,所以可以压缩

用dp[i][j]表示第i个男的,女的配对情况是j的情况下的最大值

则dp[i + 1][j | (1 << k)] = max(dp[i][j] + val[i + 1][k])

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;
const int N = 20;
const int M = (1 << 16) + 10;

struct Node {
int row, state;
Node() {}
Node(int row, int state): row(row), state(state) {}
};

int val

;
int dp
[M];
int n, cas = 1;

void init (){
scanf("%d", &n);
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
scanf("%d", &val[i][j]);
}

void solve() {
memset(dp, 0, sizeof(dp));
int all = (1 << n) - 1;

queue<Node> Q;
for (int i = 0; i < n; i++) {
Q.push(Node(0, (1 << i)));
dp[0][1 << i] = val[0][i];
}

while (!Q.empty()) {
int s = Q.front().state;
int row = Q.front().row;
Q.pop();
if (row == n - 1) continue;
for (int i = 0; i < n; i++) {
if (s & (1 << i)) continue;
if (dp[row + 1][s | (1 << i)] < dp[row][s] + val[row + 1][i]) {
dp[row + 1][s | (1 << i)] = dp[row][s] + val[row + 1][i];
Q.push(Node(row + 1, s | (1 << i)));
}
}
}
printf("Case %d: %d\n", cas++, dp[n - 1][all]);

}

int main() {
int test;
scanf("%d", &test);
while (test--) {
init();
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: