POJ 2137

题意:n(<=100)头牛各自有s(<=40)个自己喜欢的地方,FJ要把它们用绳子连成一个圈,但是每头牛都要在自己喜欢的地方之一才行,问FJ最少要用多长的绳子才行。

题解:有于数据都比较小,所以可以dp[i][j][k]代表第i头牛在j处吃草时第1头牛在k处的最小绳子,最后答案等于dp[n][i][j]+dist(0,j,n,i)的最小值。转移是s的复杂度,最后就是O(n*s^3)

View Code
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 double dp[102][42][42];
 7 struct _cow
 8 {
 9     int num;
10     double x[42],y[42];
11 } cow[102];
12 inline double getdist(int i,int ii,int j,int jj)
13 {
14     double x1=cow[i].x[ii],y1=cow[i].y[ii];
15     double x2=cow[j].x[jj],y2=cow[j].y[jj];
16     return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
17 }
18 int main()
19 {
20     int n;
21     while(scanf("%d",&n)!=EOF)
22     {
23         for(int i=1; i<=n; i++)
24         {
25             int num;
26             scanf("%d",&num);
27             cow[i].num=num;
28             for(int j=0; j<num; j++)
29                 scanf("%lf%lf",&cow[i].x[j],&cow[i].y[j]);
30         }
31         int cnt=cow[1].num,cc=cow[2].num;
32         for(int i=0; i<cc; i++)
33             for(int j=0; j<cnt; j++)
34                 dp[2][i][j]=getdist(1,j,2,i);
35         for(int i=3; i<=n; i++)
36         {
37             int ln=cow[i-1].num,nn=cow[i].num;
38             for(int j=0; j<nn; j++)
39             {
40                 for(int k=0; k<cnt; k++)
41                 {
42                     dp[i][j][k]=1e50;
43                     for(int t=0; t<ln; t++)
44                     {
45                         dp[i][j][k]=min(dp[i][j][k],dp[i-1][t][k]+getdist(i-1,t,i,j));
46                     }
47                 }
48             }
49         }
50         double ans=1e50;
51         int num=cow[n].num;
52         for(int i=0; i<cnt; i++)
53         {
54             for(int j=0; j<num; j++)
55                 ans=min(ans,dp[n][j][i]+getdist(n,j,1,i));
56         }
57         printf("%d\n",(int)floor(ans*100.0));
58     }
59     return 0;
60 }

转载于:https://www.cnblogs.com/tmeteorj/archive/2012/10/08/2715818.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值