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;
}
目录
相关文章
|
9月前
|
算法 C++
剑指offer(C++)-JZ70:矩形覆盖(算法-动态规划)
剑指offer(C++)-JZ70:矩形覆盖(算法-动态规划)
|
12天前
|
存储
【洛谷 P1255】数楼梯 题解(递归+记忆化搜索+高精度)
这是一个使用动态规划解决的“数楼梯”问题。给定楼梯数`N`,求不同上楼方式的数量。程序通过递归函数`f()`计算,其中`f(x) = f(x - 1) + f(x - 2)`,初始条件`f(1) = 1`,`f(2) = 2`。考虑到数据规模可能很大,使用了高精度加法运算。样例输入`4`,输出`5`。代码中定义了一个存储中间结果的向量`mem`,并提供了一个用于显示高精度数的`printv()`函数。
8 0
|
12天前
|
物联网
【洛谷 P1464】Function 题解(递归+记忆化搜索)
该题目定义了一个递归函数$w(a,b,c)$,具有特定的终止条件和递归规则。当$a, b, c$任一值小于等于0或大于20时,函数有特殊返回值。否则,根据$a, b, c$的相对大小关系应用不同的递归计算。给定输入是一系列的三元组$(a, b, c)$,以$-1,-1,-1$结束。程序使用记忆化搜索优化递归调用,避免重复计算。样例输入输出展示了如何计算$w(1, 1, 1)$和$w(2, 2, 2)$。
4 0
|
22天前
|
存储 算法 数据可视化
LeetCode 题目 97:动态规划、递归到广度优先搜索BFS 实现交错字符串
LeetCode 题目 97:动态规划、递归到广度优先搜索BFS 实现交错字符串
|
9月前
华为机试HJ44:Sudoku(数独问题,深度优先遍历DFS解法)
华为机试HJ44:Sudoku(数独问题,深度优先遍历DFS解法)
|
2月前
代码随想录Day45 动态规划13 LeetCode T1143最长公共子序列 T1135 不相交的线 T53最大子数组和
代码随想录Day45 动态规划13 LeetCode T1143最长公共子序列 T1135 不相交的线 T53最大子数组和
43 0
|
2月前
|
人工智能 算法 测试技术
map|动态规划|单调栈|LeetCode975:奇偶跳
map|动态规划|单调栈|LeetCode975:奇偶跳
|
9月前
Light oj 1112 - Curious Robin Hood(树状数组)
有n个数,有m组操作,1 i表示将第i个数先输出,然后置0, 2 i v 表示给第i个数加上v, 3 i j 表示求i 到 j 的和,注意,这里数组是从0开始的,而我们构造的树状数组是从1 开始的,使用在程序中要进行一定的处理。
28 0
|
9月前
|
机器学习/深度学习
light oj 1005 - Rooks(组合数学)
组合数学解法 现在n行中选出m行,C(n,m),再在n列中选出m列随便放A(n,m),答案为C(n,m)*A(n,m)。
23 0
|
9月前
|
存储 算法 C++
剑指offer(C++)-JZ69:跳台阶(算法-动态规划)
剑指offer(C++)-JZ69:跳台阶(算法-动态规划)