演算法提高 金陵十三釵 狀態亞索DP

2021-08-11 16:42:11 字數 2970 閱讀 4291

問題描述

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

所謂相似度矩陣是乙個n*n的二維陣列like[i][j]。其中i,j分別為女人的編號和學生的編號,皆從0到n-1編號。like[i][j]是乙個0到100的整數值,表示第i個女人和第j個學生的相似度,值越大相似度越大,比如0表示完全不相似,100表示百分之百一樣。每個女人都需要找乙個自己代替的女學生。

最終要使兩邊一一配對,形成乙個匹配。請程式設計找到一種匹配方案,使各對女人和女學生之間的相似度之和最大。

輸入格式

第一行乙個正整數n表示有n個秦淮河女人和n個女學生

接下來n行給出相似度,每行n個0到100的整數,依次對應二維矩陣的n行n列。

輸出格式

僅一行,乙個整數,表示可獲得的最大相似度。

樣例輸入4

97 91 68 14

8 33 27 92

36 32 98 53

73 7 17 82

樣例輸出

354資料規模和約定

對於70%的資料,n<=10

對於100%的資料,n<=13

樣例說明

最大相似度為91+92+93+73=354

對於70%的資料,直接用全排列列舉出每個女生對應的人然後求解,取最大值,時間複雜度是o(n*n!),對於n<=10,是可以接受的

對於100%的資料,可以採用狀態壓縮的辦法進行動態規劃:

dp[i][j]表示現在進行到i個女人,被占用學生的狀態為j的最大制。

將狀態j表示成二進位制,第k位為1 表示第k個學生已經被占用了。

比如j=3,二進位制是00000011,表示第1和第2個學生已經被占用。

對於初始狀態:

dp[0][j]=0    

轉移方程是:

dp[i][j]=max(dp[i-1][k]+like[i][t]) 

其中t是j中其中1個1的位置,k是j把第t位變成0的數,把所有t找一邊取個最大值再+like[i][t],就是dp[i][j] 

答案就是dp[n][2^n-1]

時間複雜度應該是o(n*2^n)

考慮到對於所有i,只和i-1項有關,所以可以減少一維空間消耗

對於n<=13是可以秒出的。

最後再貼乙份剛寫的新鮮的**:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

#include

#include

#include

#include

#define maxn 15

usingnamespacestd;

constintmaxzt=(1<<13);//最大的狀態數,

intdp[maxzt];

intlike[maxn][maxn],n;

intnumberofone(intnum)

returncnt;

}

intlowbit(intx)

intposofone(intnum)

returnpos;

}

voidwork(intx)

}

}

intmain()

演算法提高 金陵十三釵

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

藍橋杯演算法提高 金陵十三釵

思路 這道題最基本的做法就是dfs直接暴力破解,這樣的複雜度毫無疑問的o n 是不能完全ac的.那麼,看到這道題問的是最優解,那麼想必跟動態規劃能扯上關係了,但是咋一看,轉移方程可不太好寫,一開始的時候我還寫了個錯的轉移式,妄想能在o n 2 內求解.言歸正傳,使用動態規劃的話,要注意的是 在為第 ...

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

思路 深度搜尋複雜度n!過不了。考慮動態規劃 將已經選擇的列記為1,未選擇表示0,二進位制壓縮,例如110,就表示選擇了第1列和第2列。d i,t 表示當前已經匹配了i行,選擇了t這些列。狀態轉移 for int i 0 i n i 此時總的狀態數就是1 用記憶化搜尋,很好寫。include inc...