长春Online的题目,
当时读了就推出了分治+记忆化搜索,其实就是区间DP。时间不够就没写,还是太弱了。这种题目,代码量,应该在30min内A掉。
dp[i][j][k]表示处理(i,j)内,先访问k+的最小路程。
注意到k==j时,枚举dp[i][j-1][x],路径为:j+ x+ dp[i][j-1][x-1] (j-1)- j-。
k <j时,枚举dp[k+1][j][x],路径为:dp[i][k][k] (k- x+) dp[k+1][j][x]。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 #include<algorithm> 5 6 using namespace std; 7 8 const int maxn = 111; 9 const double inf = 1000000000; 10 struct Point 11 { 12 double x,y; 13 } p[maxn][2]; 14 int n; 15 16 double diss(Point a, Point b) 17 { 18 return sqrt((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y)); 19 } 20 double dis[maxn][maxn][2][2]; 21 double dp[maxn][maxn][maxn]; 22 int path[maxn][maxn][maxn]; 23 24 void dfs_out(int l,int r,int p) 25 { 26 if (l == r) 27 { 28 printf("%d+ ",p); 29 30 printf("%d-",p); 31 if (p!=n) 32 { 33 printf(" "); 34 } 35 return ; 36 } 37 int x = path[l][r][p]; 38 if (l < r) 39 { 40 if (r == p) 41 { 42 printf("%d+ ",p); 43 dfs_out(l,r-1,x); 44 printf("%d-",p); 45 if (p!=n){ 46 printf(" "); 47 } 48 } 49 else 50 { 51 dfs_out(l,p,p); 52 dfs_out(p+1,r,x); 53 } 54 } 55 return ; 56 } 57 int main() 58 { 59 while (scanf("%d", &n)==1) 60 { 61 for (int i=1; i<=n; i++) 62 { 63 for (int j=0; j<2; j++) 64 { 65 scanf("%lf%lf", &p[i][j].x, &p[i][j].y); 66 } 67 } 68 for (int i=1; i<=n; i++) 69 for (int j=1; j<=n; j++) 70 { 71 for (int ii=0; ii<2; ii++) 72 for (int jj=0; jj<2; jj++) 73 { 74 dis[i][j][ii][jj] = diss(p[i][ii],p[j][jj]); 75 } 76 } 77 78 for (int i=n; i>=1; i--) 79 { 80 for (int j=i; j<=n; j++) 81 { 82 if (i == j) 83 { 84 dp[i][i][i] = dis[i][i][0][1]; 85 path[i][i][i] = i; 86 continue; 87 } 88 for (int k=i; k<=j; k++) 89 { 90 if (k==j) 91 { 92 double tmp = inf; 93 for (int x = i; x<j; x++) 94 { 95 double temp = dp[i][j-1][x] + dis[j][x][0][0] + dis[j-1][j][1][1]; 96 if (temp < tmp) 97 { 98 tmp = temp; 99 path[i][j][k] = x; 100 } 101 } 102 dp[i][j][k] = tmp; 103 } 104 else 105 { 106 double tmp = inf; 107 for (int x=k+1; x<=j; x++) 108 { 109 double temp = dp[i][k][k] + dp[k+1][j][x] + dis[k][x][1][0]; 110 if (temp < tmp) 111 { 112 tmp = temp; 113 path[i][j][k] = x; 114 } 115 } 116 dp[i][j][k] = tmp; 117 } 118 } 119 } 120 } 121 122 double ans = inf; 123 int p = 0; 124 for (int i=1; i<=n; i++) 125 { 126 if (dp[1][n][i] <ans) 127 { 128 ans = dp[1][n][i]; 129 p = i; 130 } 131 } 132 // printf("%lf\n",ans); 133 dfs_out(1,n,p); 134 puts(""); 135 } 136 return 0; 137 }