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

 

你可能感兴趣的:(HDU)