hdu 5691 Sitting in Line (状压dp)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 5691 Sitting in Line (状压dp)相关的知识,希望对你有一定的参考价值。
1 #include<bits/stdc++.h> 2 #define lld I64d 3 using namespace std; 4 typedef long long ll; 5 int cal(int x){ 6 int ret = 0; 7 while(x){ 8 if(x & 1) ret ++; 9 x >>= 1; 10 } 11 return ret; 12 } 13 const int N = 17; 14 const int INF = 0x7f7f7f7f; 15 int dp[1<<16][N]; 16 int a[N],p[N],bits[1<<N]; 17 /** 18 * dp[i][j] : 表示 状态 i , 最后一个数是 a[j] 的最优值 19 * 20 * a[N] = 0 21 * dp[0][N] = 0 22 * dp[i | (1<<k)][k] = max(dp[i | (1 << k)][k],dp[i][j] + a[j] * a[k]); 23 * */ 24 int main(){ 25 int n,T,kase = 1; 26 scanf("%d",&T); 27 while(T--){ 28 scanf("%d",&n); 29 for(int i = 0 ; i < n ; i ++){ 30 scanf("%d%d",&a[i],&p[i]); 31 } 32 for(int i = 0 ; i < (1 << n) ; i ++){ 33 for(int j = 0 ; j <= n ; j ++){ 34 dp[i][j] = -INF; 35 } 36 } 37 for(int i = 0 ; i < (1 << n) ; i ++) bits[i] = cal(i); 38 a[n] = dp[0][n] = 0; 39 for(int i = 0 ; i < (1 << n) ; i ++){ 40 for(int j = 0 ; j <= n ; j ++){ 41 if(dp[i][j] != -INF){ 42 for(int k = 0 ; k < n ; k ++){ 43 if((i & (1 << k)) == 0 && (p[k] == -1 || p[k] == bits[i]) ){ 44 // 状态转移: 45 dp[i | (1<<k)][k] = max(dp[i | (1 << k)][k],dp[i][j] + a[j] * a[k]); 46 } 47 } 48 } 49 } 50 }
// cout << "dp[1][n] :" << dp[1][n] << endl; -INF 51 int ans = -INF; 52 for(int i = 0 ; i <= n ; i ++) ans = max(ans,dp[(1<<n)-1][i]); 53 printf("Case #%d:\n%d\n",kase++,ans); 54 } 55 }
cout << "dp[1][n] :" << dp[1][n] << endl; dp[1][n] = -INF
p[k] == -1 表示第a[k]个任意放, p[k] == bits[i] ,表示 a[k]要放在第bits[i]个
* a[N] = 0
* dp[0][N] = 0
dp[1][1] = 0
dp[11][2]
dp[101][3]
dp[1001][4]
dp[10][2] = 0
....
dp[100][3] = 0
dp[1000][4] = 0
以上是关于hdu 5691 Sitting in Line (状压dp)的主要内容,如果未能解决你的问题,请参考以下文章
hdu 5691 Sitting in Line(状压dp)