思路 :
这道题最基本的做法就是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 {
Dp[2][ 0110 ] + Like[ 2][ 0] ,
Dp[2][ 0101 ] + Like[ 2][ 1],
Dp[2][ 0011 ] + Like[ 2][ 2],
}
单说的确麻烦, 直接上代码:
#include
#include
#include
#include <memory.h>
using namespace std;
#define MAXN 14
typedef vector Vector;
int Like[MAXN][MAXN]={0};
int dp[2][1<<MAXN];
int N;
Vector V[MAXN];
// 计算n的二进制表示中1的数量
// 复杂度O( logN )
int CountOfOne( int n ){
int cnt = 0;
do{
cnt += (n&1);
}while(n>>=1);
return cnt;
}
// 获取最低位的1
// 复杂度O( logN )
inline int lowBit( int n ){ return n&(-n); }
// 获取最低位的0 的下标
// 复杂度O( logN )
int lowBitPos( int n ){
int cnt = 0;
while( n & 1 ){
++cnt;
n >>= 1;
}
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<<N); i < End; ++i)
V[ CountOfOne(i) ].push_back( i );
for( int i=0,j; i < N; ++i)
for( j=0; j < N; ++j )
scanf("%d",&Like[i][j]);
memset(dp,0,sizeof(dp));
int E=0;
// 复杂度O( 2^N ) * O( logN )
for( int i = 1; i <= N; ++i ){
E = 1-E;
for( Vector::iterator it=V[i].begin(), End=V[i].end(); it != End; ++it ){
for(int status = *it, temp=*it, times=0, lb; times < i; ++times){
lb = ~lowBit(temp);
dp[E][status] = max(dp[E][status], dp[1-E][status&lb]+Like[i-1][lowBitPos(lb)]);
temp &= lb;
}
}
}
printf("%d",dp[E][(1<<N)-1]);
return 0;
}
作者:Lonverce
来源:CSDN
原文:https://blog.csdn.net/lonverce/article/details/50164587
版权声明:本文为博主原创文章,转载请附上博文链接!