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 }
View Code

 

posted @ 2013-07-07 10:29  xxx0624  阅读(313)  评论(0编辑  收藏  举报