1. 程式人生 > >演算法提高 金陵十三釵 狀壓DP

演算法提高 金陵十三釵 狀壓DP

        思路:深度搜索複雜度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

        思路:深度搜索複雜度N!過不了。考慮動態規劃:將已經選擇的列記為1,未選擇表示0,二進位制壓縮,例如110,就表示選擇了第1列和第2列。      d(i, t)表示當前已經匹配了i行

演算法提高 金陵十三

Problem Description 在電影《金陵十三釵》中有十二個秦淮河的女人要自我犧牲代替十二個女學生去赴日本人的死亡宴會。為了不讓日本人發現,自然需要一番喬裝打扮。但由於天生材質的原因,每個人和每個人之間的相似度是不同的。由於我們這是程式設計題,

藍橋杯 演算法訓練 金陵十三dp+狀態壓縮) ----------------------------C語言——菜鳥級

/*問題描述   在電影《金陵十三釵》中有十二個秦淮河的女人要自我犧牲代替十二個女學生去赴日本人 的死亡宴會。為了不讓日本人發現,自然需要一番喬裝打扮。但由於天生材質的原因, 每個人和每個人之間的相似度是不同的。由於我們這是程式設計題,因此情況就變成了金陵

NOIP2017提高組 Day2T2寶藏 DP

題目就不說了吧。。 搜尋好像也能過,不過是啟發式才行。。何況比賽打得也是狀壓。。 其實不算很難吧,但是我比較菜所以掛了。 總是想著如何列舉,但是這題直接列舉轉移的話好像不大可做。 所以預處理出兩個狀態之間的轉移代價,即w[s1,s2]表示從s1轉移到s2

【題解】[牛客網NOIP賽前集訓營-提高組(第二場)]C.集合劃分 DP

題目連結 看了題解後還是沒寫對,只能去看Komachi大佬咋寫的了。 #include<cstdio> #include<cstring> const int N=18,MX=(1<<18)+5; int n,m,k,ban[N]

LOJ2540 隨機演算法 DP

傳送門   兩種$DP$: ①$f_{i,j}$表示前$i$次選擇,最大獨立集為$j$時達到最大獨立集的方案總數,轉移:$a.f_{i,j}+=f_{i+1,j+2^k}$(保證$k$加入後符合條件);$b.f_{i,j}+=f_{i+1,j} \times \text{現在可以放的不影響

DP】【NOIP提高組】憤怒的小鳥

這是道不算水的狀壓DP 這道題對我的吸引力很大,為什麼呢,因為它的背景是遊戲啊 題目描述 Kiana 最近沉迷於一款神奇的遊戲無法自拔。 簡單來說,這款遊戲是在一個平面上進行的。 有一架彈弓位於 (0,0)(0,0) 處,每次 Kiana 可以用它向第一象限發射

DP】poj3254 Corn Fields

一行 cstring fields while state 條件 style 狀壓 () 題意: 一塊n*m的田,1表示這個地方可以種植,0代表這個地方不能種植。植物種植還必須滿足兩株植物不能相鄰(橫豎都不行)。問共有幾種種植方法,而且當什麽都不種時認為是一種方法。 解題思

【bzoj4145】[AMPPZ2014]The Prices dp

return std sin highlight string span 題目 狀態壓縮dp print 原文地址:http://www.cnblogs.com/GXZlegend/p/6832200.html 題目描述 你要購買m種物品各一件,一共有n家商店,你到第i家

DP入門——鋪磚塊

ont 輸出 fin load www ret mil times set 題目描述 現有n*m的一塊地板,需要用1*2的磚塊去鋪滿,中間不能留有空隙。問這樣方案有多少種 輸入 輸入n,m(1<=n, m<=11) 有多組輸入數據,以m=n=0結束

[LightOJ 1018]Brush (IV)[DP]

邊界 lightoj 計算 const 擁有 for ostream 當前 blank 題目鏈接:http://lightoj.com/volume_showproblem.php?problem=1018 題意分析:平面上有不超過N個點,如今能夠隨意方向劃直線將它們劃

SGU 223 little kings BSOJ2772 DP

而且 進制 print 剪枝 描述 計算機 tex 範圍 blog 1896 [SCOI2005]互不侵犯King 【問題描述】在n*n(1<=n<=10)的棋盤上放k(0<=k<=n*n)個國王(可攻擊相鄰的8 個格子),求使它們無法互相攻擊的方

POJ 3254 Corn Fields (DP)

sign inline con cout ont tor const put 方式 題意:給定一個n*m的01矩陣,然後求有多少種方式,在1上並且1不相鄰。 析:一個簡單的狀壓DP,dp[i][s] 表示 第 i 行狀態為 s 時有多少種,然後只要處理不相鄰就行了,比賽進位

HDU 4906 Our happy ending (DP)

中一 article san mar break std 多少 滾動 con HDU 4906 Our happy ending pid=4906" style="">題目鏈接 題意:給定n個數字,每一個數字能夠是0-l,要選當中一些數字。然後使得和

POJ 1185 炮兵陣地 (DP)

pre int fine clu mat 狀態 print 優化 ans 題意:中文題。 析:dp[i][s][t] 表示第 i 行狀態為 s, 第 i-1 行為 t,然後就很簡單了,但是要超內存,實際上狀態最多才60個,所以後兩維開60就好, 然後又超時間,就一直加優化,

[BZOJ 1076][SCOI2008]獎勵關(期望+Dp

方便 double spa solution bsp 所有 一個 int stream Description 你正在玩你最喜歡的電子遊戲,並且剛剛進入一個獎勵關。在這個獎勵關裏,系統將依次隨機拋出k次寶物, 每次你都可以選擇吃或者不吃(必須在拋出下一個寶物之前做出選

HDU 4856 Tunnels(BFS+DP

pid air san void hit uil set itl pair HDU 4856 Tunnels 題目鏈接 題意:給定一些管道。然後管道之間走是不用時間的,陸地上有障礙。陸地上走一步花費時間1,求遍歷全部管道須要的最短時間。每一個管道僅僅能走一次 思

男神的約會(dp)

alt pri sof cnblogs soft 每次 div src closed 有一天男神約了學姐姐去看電影,電影院有一個活動,給你一個10*10的矩陣,每一個格子上都有一個0-9的整數,表示一共十種優惠券中的一種。 觀眾從左上角的格子開始走,走到右下角。每走到一個

dp】CDOJ1608 暑假集訓

algo name pac 開始 技術分享 只需要 memset urn cnblogs 裸的狀壓的話,很顯然……但有一個強大的優化。 就是在枚舉決策的時候,固定第一個空位置。可以證明,這樣狀態數沒有減少,但是降低了很多重復訪問。 因為你在枚舉的時候,總是可以劃分為包含第

dp】互不侵犯KING

git algorithm long long true 求解 格子 ble bool span 互不侵犯KING Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3866 Solved: 2264[Submit][Sta