HDU3362+状态压缩
dp[ i ]表示该状态下得所需花费。
1 /* 2 状态压缩dp 3 dp[i] = min( dp[ i-j ]+cost[ j ] ); 4 由i-j的状态转到i的状态 5 */ 6 #include<stdio.h> 7 #include<string.h> 8 #include<stdlib.h> 9 #include<iostream> 10 #include<math.h> 11 using namespace std; 12 const int maxn = 20; 13 const double inf = 99999999.0; 14 const int maxm = (1<<20); 15 const double eps = 1e-8; 16 struct node{ 17 double x,y; 18 }dot[ maxn ]; 19 double dp[ maxm ]; 20 double dis[ maxn ][ maxn ]; 21 double dist( int i,int j ){ 22 return sqrt( ( dot[i].x-dot[j].x )*( dot[i].x-dot[j].x )+( dot[i].y-dot[j].y )*( dot[i].y-dot[j].y ) ); 23 } 24 int main(){ 25 int n; 26 while( scanf("%d",&n),n ){ 27 int sum,cnt,flag; 28 cnt = 0; 29 sum = 0; 30 for( int i=0;i<n;i++ ){ 31 scanf("%lf%lf%d",&dot[i].x,&dot[i].y,&flag); 32 if( flag==1 ){ 33 sum += (1<<i); 34 cnt++; 35 } 36 } 37 if(( n>1&&cnt<2 )||( n==1&&cnt==0 )){ 38 printf("No Solution\n"); 39 continue; 40 } 41 for( int i=0;i<n;i++ ) 42 for( int j=0;j<n;j++ ) 43 dis[ i ][ j ] = dist( i,j ); 44 int N = (1<<n); 45 for( int i=0;i<N;i++ ) 46 dp[ i ] = inf; 47 dp[ sum ] = 0.0; 48 for( int i=sum;i<N;i++ ){ 49 if( dp[i]>inf ) continue; 50 for( int j=0;j<n;j++ ){ 51 if( i&(1<<j) )//j是固定的 52 continue; 53 double min1 = inf; 54 double min2 = inf; 55 for( int k=0;k<n;k++ ){//找出min1,min2 56 if( i&(1<<k) ){ 57 if( min1>dis[ j ][ k ] ){ 58 min2 = min1; 59 min1 = dis[ j ][ k ]; 60 } 61 else if( min2>dis[ j ][ k ] ){ 62 min2 = dis[ j ][ k ]; 63 } 64 } 65 } 66 dp[ i|(1<<j) ] = min( dp[ i|(1<<j) ],dp[i]+min1+min2 ); 67 } 68 } 69 printf("%.6lf\n",dp[ N-1 ]); 70 } 71 return 0; 72 }
keep moving...