现在的位置: 首页 > 综合 > 正文

UVA 10911 – Forming Quiz Teams

2019年02月25日 ⁄ 综合 ⁄ 共 1665字 ⁄ 字号 评论关闭

题目链接~~>

做题感悟:这题刚接触最优配对问题的第一题,开始因为数组开小了wa了一次。

解题思路:请点击~>

代码(二维):

#include<stdio.h>
#include<iostream>
#include<map>
#include<string>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std ;
const double PI = 3.1415926 ;
const double INF = 99999999 ;
const int MX =25 ;
int n ;
double dp[MX][1<<20] ; // 开数组要注意
struct node
{
    double x,y ;
}T[MX] ;
double dis(node a,node b)// 计算两点距离
{
    return sqrt(pow(a.x-b.x,2.0)+pow(a.y-b.y,2.0)) ;
}
double min(double x,double y) // 比较大小
{
    return  x < y ? x : y ;
}
void DP()
{
    for(int i=0 ;i<n ;i++)
      for(int s=0 ;s<(1<<(i+1)) ;s++)
      {
          s ? dp[i][s]=INF : dp[i][s]=0 ;
          if(s&(1<<i))
          {
             for(int j=i-1 ;j>=0 ;j--)
               if(s&(1<<j))
                  dp[i][s]=min(dp[i][s],dis(T[i],T[j])+dp[i-1][s^(1<<i)^(1<<j)]) ;
          }
          else if(i)
             dp[i][s]=dp[i-1][s] ;  // i-1 的最优解复制下来
      }
}
int main()
{
    char s[MX] ;
    int q=1 ;
    while(~scanf("%d",&n)&&n)
    {
        n=n*2 ;
        for(int i=0 ;i<n ;i++)
           scanf("%s%lf%lf",s,&T[i].x,&T[i].y) ;
        DP() ;
        printf("Case %d: %.2lf\n",q++,dp[n-1][(1<<n)-1]) ;
    }
    return 0 ;
}

代码(一维):

#include<stdio.h>
#include<iostream>
#include<map>
#include<string>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std ;
const double PI = 3.1415926 ;
const double INF = 99999999 ;
const int MX =25 ;
double dp[1<<MX] ;
int n,S ;
struct node
{
    double x,y ;
}T[MX] ;
double dis(node a,node b)
{
    return sqrt(pow(a.x-b.x,2.0)+pow(a.y-b.y,2.0)) ;
}
double min(double x,double y)
{
    return  x > y ?  y : x ;
}
void DP()
{
    for(int s=1 ;s<S ;s++)
    {
        dp[s]=INF ;
        for(int i=n-1 ;i>=0 ;i--)
         if(s&(1<<i))
         {
             for(int j=i-1 ;j>=0 ;j--)
              if(s&(1<<j))
                 dp[s]=min(dp[s],dis(T[i],T[j])+dp[s^(1<<i)^(1<<j)]) ;
         }
    }
}
int main()
{
    char s[MX] ;
    int q=1 ;
    while(~scanf("%d",&n)&&n)
    {
        n=n*2 ;
        S=1<<n ;
        for(int i=0 ;i<n ;i++)
          scanf("%s%lf%lf",s,&T[i].x,&T[i].y) ;
        DP() ;
        printf("Case %d: %.2lf\n",q++,dp[S-1]) ;
    }
    return 0 ;
}

 

 

 

 

 

 

抱歉!评论已关闭.