Aspen Avenue
Aspen Avenue |
``Phew, that was the last one!‘‘ exclaimed the garden helper Tim as he threw the last tree plant to the ground. His employer, countess Esmeralda Hunt who owned the estate, has ordered him to arrange an avenue of aspen trees along both sides of the front road leading up to the house. The first trees in the avenue are supposed to be planted at the very beginning of the road, and the last trees of the avenue at the very end of the road. Tim, who was constantly being reminded of her sense of accuracy, knew that the countess would insist on the trees being placed in perfectly aligned tree pairs, one on each side of the road, and with exactly the same spacing between the pairs along the road. However, when bringing the tree plants to the estate, Tim had just dropped them arbitrarily along the left side of the road and was now facing the task of moving the trees to their correct positions to meet the countess‘s requirements. Being stronger in mind than in arms, and since it was time for a coffee break anyway before he started digging, he sat down to figure out which trees to move to which positions so as to minimize the total (Euclidean) distance that he had to move the trees.
Input
The input file contains several test cases, each of them as described below.The input starts with a positive even integer N between 4 and 2000 (inclusive), giving the total number of trees in the avenue. The next line contains two integers L and W , where 1L10000 is the length of the road, in meters, and 1W20 is the width of the road, in meters. The next N lines each describe where Tim had dropped of the trees. Each such line contains an integer 0pL indicating the position of a tree plant along the left side of the road, measured in meters from the start of the road.
Output
For each test case, write to the output the smallest total number of meters the tree plants need to be moved, on a line by itself. The answer should be given with an absolute or relative error of at most 10-6 .
Sample Input
4 10 1 1 0 10 10 6 10 1 0 9 3 5 5 6
Sample Output
2.4142135624 9.2853832858
题目大意就是将n棵树从右边 零散分布的位置上移到两边规定的位置(等间距) 使移动距离最小
思路:DP+贪心
DP(left,right) = min(DP(left+1,right)+dis(tree[left+right])to curleft,DP(left,right+1)+dis to curright)
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <string> #include <algorithm> #include <queue> #include <cmath> using namespace std; const double INF = 1e16; const int maxn = 1000+10; int n,L,W; double dp[maxn][maxn],ans,dis,tree[maxn*2]; bool vis[maxn][maxn]; double getdis(double a,double b){ return sqrt(a*a+b*b); } double dfs(int left,int right){ if(left==n/2&&right==n/2) return 0; if(vis[left][right]) return dp[left][right]; vis[left][right] = 1; double ans = INF; if(left<n/2) ans = min(dfs(left+1,right)+getdis(abs(tree[left+right]-left*dis),W*1.0),ans); if(right<n/2) ans = min(dfs(left,right+1)+abs(tree[left+right]-right*dis),ans); return dp[left][right] = ans; } int main(){ while(cin >> n){ memset(vis,0,sizeof vis); for(int i = 0; i < n/2; i++) for(int j = 0; j < n/2; j++) dp[i][j] = INF; cin >> L >> W; for(int i = 0; i < n; i++) scanf("%lf",&tree[i]); sort(tree,tree+n); dis = L*1.0/(n/2.0-1); ans = dfs(0,0); printf("%.8lf\n",ans); } return 0; }