HDU 1565 方格取数(1)(状态压缩DP)
水过的,就是普普通通的枚举上一层和这一层,应该可以加上队列优化,降复杂度。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #define eps 1e-9 6 #define INF -10000000 7 #define ll __int64 8 using namespace std; 9 int dp[21][18000],p[21][21],o[18000]; 10 int main() 11 { 12 int n,i,j,k,u,tem,num; 13 while(scanf("%d",&n)!=EOF) 14 { 15 memset(dp,0,sizeof(dp)); 16 for(i = 1; i <= n; i ++) 17 { 18 for(j = 1; j <= n; j ++) 19 scanf("%d",&p[i][j]); 20 } 21 num = 1; 22 for(i = 1; i < 1<<n; i ++) 23 { 24 if(i&(i<<1)||i&(i>>1)) 25 { 26 continue; 27 } 28 dp[1][num] = 0; 29 o[num] = i; 30 for(j = 0; j <= n-1; j ++) 31 { 32 if(i&(1<<j)) 33 { 34 dp[1][num] += p[1][j+1]; 35 } 36 } 37 num ++; 38 } 39 for(i = 2; i <= n; i ++) 40 { 41 for(k = 1; k < num; k ++) 42 { 43 for(j = 1; j < num; j ++) 44 { 45 if(o[j]&o[k]) 46 continue; 47 tem = 0; 48 for(u = 0; u <= n-1; u ++) 49 { 50 if(o[k]&(1<<u)) 51 tem += p[i][u+1]; 52 } 53 if(dp[i][k] < dp[i-1][j]+tem) 54 dp[i][k] = dp[i-1][j]+tem; 55 } 56 } 57 } 58 /*for(i = 1; i <= n; i ++) 59 { 60 for(j = 1; j < num; j ++) 61 { 62 printf("%d ",dp[i][j]); 63 } 64 printf("\n"); 65 }*/ 66 tem = 0; 67 for(i = 1; i < num; i ++) 68 { 69 if(tem < dp[n][i]) 70 tem = dp[n][i]; 71 } 72 printf("%d\n",tem); 73 } 74 return 0; 75 }