思路:深度搜索复杂度N!过不了。考虑动态规划:将已经选择的列记为1,未选择表示0,二进制压缩,例如110,就表示选择了第1列和第2列。

d(i, t)表示当前已经匹配了i行,选择了t这些列。状态转移:

for(int i = 0; i < n; ++i) {
		int x = 1 << i;
		if(x & val) d = max(d, like[row][i] + dfs(row+1, val - x, k-1));
	}

此时总的状态数就是1<<n,相比N!是极大的优化,减少了很多重复情况的搜索。

用记忆化搜索,代码很好写。

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <utility>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define eps 1e-10
#define inf 0x3f3f3f3f
#define PI pair<int, int>
typedef long long LL;
const int maxn = 13 + 5;
int like[maxn][maxn], dp[maxn][1<<13];
int n, ans;
int dfs(int row, int val, int k) { //row表示行,k表示当前选择了多少列
	if(dp[row][val] != -1) return dp[row][val];
	int &d = dp[row][val];
	if(k == 1) { //边界
		for(int i = 0; i < n; ++i) {
			int x = 1 << i;
			if(x & val) return d = like[row][i];
		}
	}
	for(int i = 0; i < n; ++i) {
		int x = 1 << i;
		if(x & val) d = max(d, like[row][i] + dfs(row+1, val - x, k-1));
	}
	return d;
}
int main() {
	while(scanf("%d", &n) == 1) {
		for(int i = 0; i < n; ++i)
			for(int j = 0; j < n; ++j) {
				scanf("%d", &like[i][j]);
			}
		memset(dp, -1, sizeof(dp));
		int start = (1<<n)-1;
		printf("%d\n", dfs(0, start, n));
	}
	return 0;
}

如有不当之处欢迎指出!

算法提高 金陵十三钗 状压DP的更多相关文章

  1. 计蒜客 31436 - 提高水平 - [状压DP]

    题目链接:https://nanti.jisuanke.com/t/31436 作为一名车手,为了提高自身的姿势水平,平时的练习是必不可少的.小 J 每天的训练包含 $N$ 个训练项目,他会按照某个顺 ...

  2. 「算法笔记」状压 DP

    一.关于状压 dp 为了规避不确定性,我们将需要枚举的东西放入状态.当不确定性太多的时候,我们就需要将它们压进较少的维数内. 常见的状态: 天生二进制(开关.选与不选.是否出现--) 爆搜出状态,给它 ...

  3. 【算法系列学习】状压dp [kuangbin带你飞]专题十二 基础DP1 D - Doing Homework

    https://vjudge.net/contest/68966#problem/D http://blog.csdn.net/u010489389/article/details/19218795 ...

  4. 算法复习——状压dp

    状压dp的核心在于,当我们不能通过表现单一的对象的状态来达到dp的最优子结构和无后效性原则时,我们可能保存多个元素的有关信息··这时候利用2进制的01来表示每个元素相关状态并将其压缩成2进制数就可以达 ...

  5. 【洛谷5492】[PKUWC2018] 随机算法(状压DP)

    点此看题面 大致题意: 用随机算法求一张图的最大独立集:每次随机一个排列,从前到后枚举排列中的点,如果当前点加入点集中依然是独立集,就将当前点加入点集中,最终得到的点集就是最大独立集.求这个随机算法的 ...

  6. 算法笔记-状压dp

    状压dp 就是把状态压缩的dp 这样还是一种暴力但相对于纯暴力还是优雅的多. 实际上dp就是经过优化的暴力罢了 首先要了解位运算 给个链接吧 [https://blog.csdn.net/u01337 ...

  7. loj2540 「PKUWC2018」随机算法 【状压dp】

    题目链接 loj2540 题解 有一个朴素三进制状压\(dp\),考虑当前点三种状态:没考虑过,被选入集合,被排除 就有了\(O(n3^{n})\)的转移 但这样不优,我们考虑优化状态 设\(f[i] ...

  8. NOIP2016提高A组 A题 礼物—概率状压dp

    题目描述 夏川的生日就要到了.作为夏川形式上的男朋友,季堂打算给夏川买一些生 日礼物. 商店里一共有n种礼物.夏川每得到一种礼物,就会获得相应喜悦值Wi(每种礼物的喜悦值不能重复获得). 每次,店员会 ...

  9. 有关状压DP

    [以下内容仅为本人在学习中的所感所想,本人水平有限目前尚处学习阶段,如有错误及不妥之处还请各位大佬指正,请谅解,谢谢!] 引言 动态规划虽然已经是对暴力算法的优化,但在某些比较特别的情况下,可以通过一 ...

随机推荐

  1. 00_HTML入门第一天

    HTML入门 body标记的常见属性:bgcolor 设置背景颜色:text 设置文本颜色:link 设置链接颜色:vlink 设置已经访问了的链接颜色:alink 正在点击的链接颜色: meta是单 ...

  2. 【转】Linux上vi(vim)编辑器使用教程

    Linux上vi(vim)编辑器使用教程 ------------------------------------------------------------ ikong ------------ ...

  3. Macaca拓展自己控件的方法

    https://github.com/macacajs/wd.py/blob/3bc4334bcb68733cb230b59d6164110053fd1c16/tests/macaca/test_ut ...

  4. Failed to get D-Bus connection: Operation not permitted解决

    docker中安装centos无法使用systemctl命令管理进程,报以下错误: Failed to get D-Bus connection: Operation not permitted 原因 ...

  5. [C#][Newtonsoft.Json] Newtonsoft.Json 序列化时的一些其它用法

    Newtonsoft.Json 序列化时的一些其它用法 在进行序列化时我们一般会选择使用匿名类型 new { },或者添加一个新类(包含想输出的所有字段).但不可避免的会出现以下情形:如属性值隐藏(敏 ...

  6. Electron应用使用electron-builder配合electron-updater实现自动更新(windows + mac)

    发客户端一定要做的就是自动更新模块,否则每次版本升级都是一个头疼的事.下面是Electron应用使用electron-builder配合electron-updater实现自动更新的解决方案. 1.安 ...

  7. [DeeplearningAI笔记]ML strategy_2_2训练和开发/测试数据集不匹配问题

    机器学习策略-不匹配的训练和开发/测试数据 觉得有用的话,欢迎一起讨论相互学习~Follow Me 2.4在不同分布上训练和测试数据 在深度学习时代,越来越多的团队使用和开发集/测试集不同分布的数据来 ...

  8. pip相关工具使用小结

    最近写taffy的时候用到了两个pip相关的小工具. 一个是pip-review批量更新lib库,一个是pipreqs生成基于项目的requirements.txt. 1. pip相关命令 #更新单个 ...

  9. Django的思维导图

    本人在学习Django的过程中整理的一些知识点 现在整理成思维导图,在以后查阅的时候可以方便自己.

  10. ABAP系统值

    SY-SUBRC:语句执行后的返回值,0表示成功 SY-DATUM:当前服务器日期 SY-UZEIT:当前服务器时间 SY-ULINE:255长度的水平线 SY-VLINE:垂直线 SY-INDEX: ...