poj 2677 双调欧几里得 动态规划

    dp[i][j] 表示快的人走到i,慢的人走到j时的最小路程 (j<i)
    从左到右对于每个点要么给走的快的人,要么给走的慢的人
    初始化 dp[i][j]=INF
     
    状态转移方程:
    f[i+1][i] = min{f[i+1][i], f[i][j]+dis[j][i+1]} 此前为f[i][j],当前点i+1分配给j 

    f[i+1][j] = min{f[i+1][j], f[i][j]+dis[i][i+1]} 此前为f[i][j],当前点i+1分配给i 

    其中 0<=j<i
    
    最后 结果为 min(f[n][i]+dis(i,n)) 其中 i<n 

View Code
#include<cstdio>
#include<cstring>
#include<cmath>
double dp[100][100];
struct point {
double x,y;
}p[100];
double dis(point a,point b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double min(double a,double b){
return a<b?a:b;
}
int main(){
int n,i,j;
while(scanf("%d",&n)!=EOF){
for(i=0;i<n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
memset(dp,127,sizeof(dp));
dp[1][0]=dis(p[0],p[1]);
for(i=0;i<n;i++){
for(j=0;j<i;j++){
dp[i+1][i]=min(dp[i+1][i],dp[i][j]+dis(p[j],p[i+1]));
dp[i+1][j]=min(dp[i+1][j],dp[i][j]+dis(p[i],p[i+1]));
}
}
double ans=1000000000;
for(i=0;i<n-1;i++)
ans=min(ans,dp[n-1][i]+dis(p[i],p[n-1]));
printf("%.2lf\n",ans);
}
return 0;
}

 

posted @ 2012-01-29 18:08  Because Of You  Views(818)  Comments(0Edit  收藏  举报