题意: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 }