light oj 1011 - Marriage Ceremonies (状态压缩+记忆化搜索)

简介: light oj 1011 - Marriage Ceremonies (状态压缩+记忆化搜索)

  大概题意是有n个男的n个女的(原谅我这么说,我是粗人),给你一个n*n的矩阵,第i行第j列表示第i个女(男)对第j个男(女)的好感度,然后要安排n对相亲,保证都是正常的(无搞基百合之类的),然后求怎么安排能使好感度和最大,求出最大值。



   开始试了纯暴力的方法,时间复杂度是n!果断超时


#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
int vis[17];
int n, ans, sum;
int map[19][19];
void dfs(int x)
{
    if (x == n+1)
    {
        ans = max(ans, sum);
        return;
    }
    for (int i = 1; i <= n; i++)
    {
        if (vis[i] == 0)
        {
            sum += map[x][i];
            vis[i] = 1;
            dfs(x+1);
            vis[i] = 0;
            sum -= map[x][i];
        }
    }
}
int main()
{
    int t;
    cin >> t;
    for (int kase = 1; kase <= t; kase++)
    {
        cin >> n;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                cin >> map[i][j];
        sum = 0;
        ans = 0;
        memset(vis, 0, sizeof(vis));
        dfs(1);
        cout << "Case " << kase << ": " << ans << endl;
    }
    return 0;
}


后来因为一个小小的弱智的错误 wa了5  6次。代码中用了很多位运算,通过位运算很方便的把状态进行了压缩存储起来。

//2013-06-25-22.05
#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
using namespace std;
const int maxn = 1<<16;
int vis[17];
int n, ans, sum;
int map[19][19];
int dp[maxn];
int dfs(int x, int d)
{
    if (x == 0)
        return 0;
    if (dp[x])
        return dp[x];
    for (int i = 0; i < n; i++)
    {
        if (x&(1<<i))
            dp[x] = max(dfs(x^(1<<i), d-1)+map[i+1][d], dp[x]);
    }
    return dp[x];
}
int main()
{
    int t;
    cin >> t;
    for (int kase = 1; kase <= t; kase++)
    {
        cin >> n;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                cin >> map[i][j];
        memset(dp, 0, sizeof(dp));
        ans = dfs((1<<n)-1, n);
        printf("Case %d: %d\n", kase, ans);
    }
    return 0;
}
目录
相关文章
|
7月前
【每日一题Day114】LC1223 掷骰子模拟 | 记忆化搜索+dp
【每日一题Day114】LC1223 掷骰子模拟 | 记忆化搜索+dp
59 0
|
算法 C++
剑指offer(C++)-JZ70:矩形覆盖(算法-动态规划)
剑指offer(C++)-JZ70:矩形覆盖(算法-动态规划)
|
7月前
|
机器学习/深度学习
【每日一题Day271】LC918环形子数组的最大和 | 分类讨论 + dp
【每日一题Day271】LC918环形子数组的最大和 | 分类讨论 + dp
59 0
【每日一题Day271】LC918环形子数组的最大和 | 分类讨论 + dp
|
机器学习/深度学习
light oj 1005 - Rooks(组合数学)
组合数学解法 现在n行中选出m行,C(n,m),再在n列中选出m列随便放A(n,m),答案为C(n,m)*A(n,m)。
40 0
Light oj 1112 - Curious Robin Hood(树状数组)
有n个数,有m组操作,1 i表示将第i个数先输出,然后置0, 2 i v 表示给第i个数加上v, 3 i j 表示求i 到 j 的和,注意,这里数组是从0开始的,而我们构造的树状数组是从1 开始的,使用在程序中要进行一定的处理。
45 0
|
算法 C++
剑指offer(C++)-JZ71:跳台阶扩展问题(算法-动态规划)
剑指offer(C++)-JZ71:跳台阶扩展问题(算法-动态规划)
|
机器学习/深度学习 算法 C++
剑指offer(C++)-JZ61:扑克牌顺子(算法-模拟)
剑指offer(C++)-JZ61:扑克牌顺子(算法-模拟)
|
存储 算法 C++
剑指offer(C++)-JZ69:跳台阶(算法-动态规划)
剑指offer(C++)-JZ69:跳台阶(算法-动态规划)
|
SQL Shell
HDU-4348 To the moon(主席树区间修改 永久化标记)
HDU-4348 To the moon(主席树区间修改 永久化标记)
150 0
HDU-4348 To the moon(主席树区间修改 永久化标记)
|
Java BI 机器学习/深度学习