Chapter_9 DP : uva1347 tour (bitonic tour)
https://cn.vjudge.net/problem/UVA-1347 这道题居然可以O(n^2)解决,让我太吃惊了!!! 鄙人见识浅薄,这其实是一个经典问题: bitonic tour. 它的定义是:
要得出(O(n^2))的DP算法,需要几步转化: 首先,计算从左到右再回来的路径长度很麻烦(因为这样回来时要标记所有走过的点,状态(2^n)),不可行. 然后,为了防止集合的标记,我们定义以下状态: 因为每次每个人都在向右走,所以只要讨论一下是那个人走到了(i+1)就可以了. 这就是状态转移方程: f[i+1][i] = min(f[i+1][i],f[i][j] + dist(j,i+1)); f[i+1][j] = min(f[i+1][j],f[i][j] + dist(i,i+1));
为何我们不会漏掉可能的情况? code#include<bits/stdc++.h> using namespace std; typedef long long ll; #define rep(_i,_st,_ed) for(int _i = (_st); _i <= (_ed); ++_i) #define per(_i,_ed,_st) for(int _i = (_ed); _i >= (_st); --_i) inline int read(){int ans = 0,f = 1; char c = getchar();while(c < ‘0‘ || c > ‘9‘) f = (c == ‘-‘) ? -1 : f,c = getchar();while(‘0‘ <= c && c <= ‘9‘) ans = ans*10 + c - ‘0‘,c = getchar();return ans;} const int maxn = 1005; double f[maxn][maxn]; struct poi{ double x,y; bool operator < (const poi &rhs) const{ return x < rhs.x; } }p[maxn]; int n; #define sqr(_x) ((_x)*(_x)) double dist(int a,int b){ return sqrt(sqr(p[a].x-p[b].x) + sqr(p[a].y - p[b].y)); } signed main(){ while(cin >> n) { rep(i,1,n) cin >> p[i].x >> p[i].y; if(n == 1) { puts("0.00"); continue; } sort(p+1,p+n+1); rep(i,n) rep(j,n) f[i][j] = 1e10; //i > j f[2][1] = dist(1,2); rep(i,2,i-1){ f[i+1][i] = min(f[i+1][i],i+1)); } printf("%.2fn",f[n][n-1] + dist(n,n-1)); } return 0; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |