LightOJ - 1011 Marriage Ceremonies(状压DP)

来源:互联网 发布:access数据库管理软件 编辑:程序博客网 时间:2024/05/22 07:00

题目大意:给你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[N][N];int dp[N][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;}
0 0
原创粉丝点击