青蛙的烦恼 (frog.pas/c/cpp)
池塘中有n片荷叶恰好围成了一个凸多边形,有一只小青蛙恰好站在1号荷叶上,小青蛙想通过最短的路程遍历所有的荷叶(经过一个荷叶一次且仅一次),小青蛙可以从一片荷叶上跳到另外任意一片荷叶上。
输入数据(frog.in)
第一行为整数n,荷叶的数量。
接下来n行,每行两个实数,为n个多边形的顶点坐标,按照顺时针方向给出。保证不会爆double。
输出数据(frog.out):
遍历所有荷叶最短路程,请保留3位小数,无Checker。
样例输入和输出
4 50.0 1.0 5.0 1.0 0.0 0.0 45.0 0.0 | 50.211 |
数据范围:
对于所有数据,0<n<=720
可以看出来,青蛙遍历的最短路线一定不会相交。
这样,我们可以得出一个结论,就是青蛙在一号结点只能跳到2号结点或者n号结点。如果青蛙跳到了2号结点,则问题转化为:从2出发,遍历2..n一次仅一次的最短距离。如果青蛙跳到了n号结点,则问题转化为:从n出发,遍历2..n一次仅一次的最短距离
根据这个思维,定义状态:f[s,L,0]表示从s出发,遍历s..s+L-1一次且仅一次的最短距离,f[s,l,1]表示从s+L-1出发,遍历s..s+L-1一次且仅一次的最短距离。
则状态转移方程为:
F[s,L,0]=min{
(跳到s+1) f[s+1,L-1,0] + dis(s,s+1),
(跳到s+L-1) f[s+1,L-1,1] + dis(s,s+L-1)
}
F[s,L,1]=min{
(跳到s) f[s,L-1,0] + dis(s,s+L-1),
(跳到s+L-2) f[s,L-1,1] + dis(s+L-1,s+L-2)
}
状态总数为n^2,状态转移的复杂度为O(1),总的时间复杂度为O(n^2)
注意,这里l是终点,外循环应该是l
C 程序:
pascal: