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 }

你可能感兴趣的:(poj)