/** Problem:ZOJ3471-Most Powerful. Reference:http://blog.csdn.net/magicnumber/article/details/6182891 Knowledge point:状态压缩DP Thought: 根据炮兵阵地(那是别的题)和这道题,还有一次多校的经验(就是那个类似拼图的那个题,给你 几个块问你能拼多大的长方形),貌似状态数少的,就可以用状态压缩。 比如这道题,N <= 10,并且一个气体只有“用”和“没用”两种属性,那么就可以用二进制表示状态。 2^10可以用一个int存储。那么rp[i]中对应的i的二进制表示,就代表了一种状态。状态的转移就在 rp[i]和rp[j]之间进行。 (rp数组和dp数组表示的意思相同,后文不再赘述。由于本人靠人品进行动态规划,故起名如此) 状态转移方程为: dp[i|cst[j]]=Max(dp[i|cst[j]],dp[i]+map[k][j]); map[k][j]表示的是用j撞k获得的能量值。 唔,跟我第一次想的不一样。就是说,存在类似 0100000,0010000,00010000...(分别表示总共8个气体,用了第二个,第三个,第四个气体,用以举例子) 这种状态,我刚开始想的是直接就是01100000(就是直接两个气体对撞)…… 【注意,我的想法是错误的,这是写给我自己看的,你们无视就好】 那么0100000代表的就是第二个气体已经用过了。 注意,跟谁撞了,这不重要。重要的是用掉了哪个气体。 ————————————关于dp[i|csj[j]]=max(dp[i|cst[j]],dp[i]+map[k][j]);的证明如下—————————————— 假设剩下最后两种气体 那么最优解一定是两种气体i,j中map[i][j],map[j][i]最大的。 而且,对于最优解来说,这时候(剩下两种气体的时候)已经获得的能量肯定是n-2种气体对撞获得能量最大的 符合最优子结构。 状态转移方程也是根据以上推出来的。 这个。。。只能意会啊,我真的证明不明白T^T,自己用样例看一下就知道了。 */ #include <iostream> #include <cstring> #include <cstdlib> #include <algorithm> #include <cstdio> using namespace std; const int MAX_SIZE = 15; const int MAX_BINARY = 1024 + 1; // avoid overflow. int power[MAX_SIZE][MAX_SIZE]; int dp[MAX_BINARY]; int bin[] = { 1,2,4,8,16,32,64,128,256,512,1024 } ;// 2^10 = 1024; int solve(int N) { int maxV = 0; for(int i = 0 ; i < bin[N] ; i++) //expand every state. { for(int j = 0 ; j < N; j++) { if( ( i & bin[j] ) != 0 ) continue; //gas j has been used. for(int k = 0 ; k < N ; k++) { if( ((i & bin[k])==0) && (k != j) ) { dp[i | bin[j]] = max(dp[i | bin[j]],dp[i]+power[k][j]); } } } } for(int i = 0 ; i < bin[N] ; i++) { maxV = max(maxV,dp[i]); } return maxV; } int main() { #ifndef ONLINE_JUDGE freopen("B:\\acm\\SummerVacation\\DP-II\\A.in","r",stdin); freopen("B:\\acm\\SummerVacation\\DP-II\\A.out","w",stdout); #endif int N,res; while(scanf("%d",&N) != EOF && N) { memset(dp,0,sizeof(dp)); for(int i = 0 ; i < N ; i++) { for(int j = 0 ; j < N ; j++) { scanf("%d",&power[i][j]); } } res = solve(N); printf("%d\n",res); } #ifndef ONLINE_JUDGE fclose(stdin); fclose(stdout); #endif return 0; }