思路 :
這道題最基本的做法就是dfs直接暴力破解, 這樣的複雜度毫無疑問的o( n! ), 是不能完全ac的. 那麼, 看到這道題問的是最優解, 那麼想必跟動態規劃能扯上關係了, 但是咋一看, 轉移方程可不太好寫, 一開始的時候我還寫了個錯的轉移式, 妄想能在o(n^2)內求解...*_*...
言歸正傳, 使用動態規劃的話, 要注意的是 : 在為第 i 個妓女匹配時, 需要在前 i-1 個妓女的所有匹配情況中作綜合規劃, 那麼, 如何記錄前 i-1 個妓女的匹配方式便成了首要問題. 因為可選學生的人數n不多於13, 所以可以利用二進位制的特性做壓縮記錄:
比如:
00000000 表示1個人都沒選
00010000 表示選擇了第5個***( 從右開始數 )
00010010 表示選擇了第5和第2個***( 從右開始數 )
所以, dp[ i ][ status ]表示前 i 個妓女以status方式選***時的最優相似度, 其中, status二進位制中1的數量必然為 i .
樹狀陣列中介紹過用" lowbit( x ) = x & (-x) "的方式來巧妙地提取出x的二進位制中最低位的1 .
相似地, " x & ~lowbit(x)"的方式可以巧妙地去除x的二進位制中最低位的1
於是, 對於status, 我們可以交替採用上述方法來遍歷其中所有的1, 或依次地單獨剔除status中的每個1
那麼:
dp[ i ][ status ] = max( dp[ i-1 ][ 單獨剔除1的status ] + like[ i -1 ][ 提取出來的那個1表示第幾個*** ] );
比如(以下status以二進位制表示) :
dp[ 3 ][ 0111 ] =max
單說的確麻煩, 直接上**:
#include #include #include #include using namespace std;
#define maxn 14
typedef vectorvector;
int like[maxn][maxn]=;
int dp[2][1<>=1);
return cnt;
}// 獲取最低位的1
// 複雜度o( logn )
inline int lowbit( int n )
// 獲取最低位的0 的下標
// 複雜度o( logn )
int lowbitpos( int n )
return cnt;
}int main(int argc, char** argv) {
scanf("%d",&n);
// 集合v[i]表示 : 二進位制下1的數量為i的數的集合
// 複雜度o( 2^n ) * o( logn )
for( int i = 0, end=(1<
演算法提高 金陵十三釵
problem description在電影 金陵十三釵 中有十二個秦淮河的女人要自我犧牲代替十二個女學生去赴日本人的死亡宴會。為了不讓日本人發現,自然需要一番喬裝打扮。但由於天生材質的原因,每個人和每個人之間的相似度是不同的。由於我們這是程式設計題,因此情況就變成了金陵n釵。給出n個女人和n個學生...
演算法提高 金陵十三釵 狀壓DP
思路 深度搜尋複雜度n!過不了。考慮動態規劃 將已經選擇的列記為1,未選擇表示0,二進位制壓縮,例如110,就表示選擇了第1列和第2列。d i,t 表示當前已經匹配了i行,選擇了t這些列。狀態轉移 for int i 0 i n i 此時總的狀態數就是1 用記憶化搜尋,很好寫。include inc...
藍橋杯 金陵十二釵
演算法提高 金陵十三釵 時間限制 1.0s 記憶體限制 256.0mb 金陵十三釵 本題難度 難 本題占分比例 5 問題描述 在電影 金陵十三釵 中有十二個秦淮河的女人要自我犧牲代替十二個女學生去赴日本人的死亡宴會。為了不讓日本人發現,自然需要一番喬裝打扮。但由於天生材質的原因,每個人和每個人之間的...