思路:深度搜索复杂度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. python_如何为创建大量实例节省内存?

    案例: 某网络游戏中,定义了玩家类Player(id, name, status,....),每有一个在线玩家,在服务器程序内有一个Player的实例,当在线人数很多时,将产生大量实例(百万级别) 需 ...

  2. JavaScript中事件绑定的三种方式

    JavaScript使得网页与用户友好交互,在使用 js 进行时间绑定的时候有三种绑定方式. 第一种:初学者以及普通写法 <div id="dom0"> <inp ...

  3. maven(项目管理工具系列 maven 总结二)

    ♣maven是什么? ♣maven下载.安装 ♣了解maven仓库 ♣eclipse配置maven ♣创建maven项目 ♣把maven项目转化为web项目 1.maven是什么? Maven是一个项 ...

  4. MySQL主从复制-xtrabackup的使用与延时复制(附原理图)

    标签(linux): mysql 笔者Q:972581034 交流群:605799367.有任何疑问可与笔者或加群交流 xtrabackup是percona公司针对MySQL开发的一款开源的物理备份工 ...

  5. 企业级Docker私有仓库部署(https)

    部署环境 Centos7.3 x64 docker-ce-17.06.0 docker-compose-1.15.0 Python-2.7.5(系统默认) 部署目标 使用HTTPS协议 支持Clair ...

  6. java 数组与集合(list)相互转化

    上代码 package com.core.array2collection; import java.util.ArrayList; import java.util.Arrays; import j ...

  7. Eclipse启动报错[ out of memory error has occurred ]或[ An internal error occurred while showing an internal error ]

    自我总结,有什么需要纠正或更好的方案,请告知,谢谢! 最近上来看到好多同学都遇到了这个问题,之前我也好几次碰到这个问题,很是恼火,什么没干,eclipse一开电脑就卡死了,后来发现不管是新打开ecli ...

  8. Python CRM项目八

    自定义用户认证 目的:实现Django自定义的认证系统,在生产环境都是根据此代码进行定制的 步骤: 1.在settings文件中配置要使用的类 #命名规则 app名称.类名 AUTH_USER_MOD ...

  9. SQL作业二

    目的:通过加载chinook_db文件来把数据导入到sqllite,根据题目的要求进行查询 1.sql语句的基本语法 2.join多表查询的用法 3.group by分组的用法 4.order by排 ...

  10. Directx3d绘制包围体并控制光照效果

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...