Tour Uva1347(DP)

刘汝佳给这道题的分析真的妙。太大佬了。

1.从左到右再回来不太方便思考,可以改成:两个人同时从最左点出发,沿着两条不同
的路径走,最后都走到最右点,且除了起点和终点外其余每个点恰好被一个人经过。 这样,
就可以用
d(i,j)表示第一个人走到i,第二个人走到j,还需要走多长的距离。 

这样换个方式思考就大大减少了复杂度!


2.好像很难保证两个人不会走到相同的点。 例如,
计算状态
d(i,j)时,能不能让i走到i1呢?不知道,因为从状态里看不出来i1有没有被j
过。 换句话说,状态定义得不好,导致转移困难

3.下面修改一下:d(i,j)表示1max(i,j)全部走过,且两个人的当前位置分别是ij,还需
要走多长的距离。 不难发现
d(i,j)=d(j,i),因此从现在开始规定在状态中ij。 这样,不管是
哪个人,下一步只能走到
i1 , i2,…这些点。 可是,如果走到i2,情况变成了“1ii
2,但是i1没走过,无法表示成状态!怎么办?禁止这样的决策!也就是说,只允许其中
一个人走到
i1,而不能走到i2, i3,…。 换句话说,状态d(i,j)只能转移到d(i1,j)d(i
1,i)

4.状态总数有O(n2)个,每个状态的决策只有两个,因此总时间复杂度为O(n2)


这个状态转移:d(i,j)只能转移到d(i1,j)d(i1,i)只适合递归记忆化搜索求解,因为我们不能事先知道

i+1的状态,我尝试过从后往前推,也是不可能的。(根据对称性也能想明白)。

如果写成循环递推的形式需要对状态转移方程进行修改,d(i, j)的得来应该分两种,j < i - 1 和j  == i  - 1时,

这两种递推需要分开写。d(i,j)= d(i - 1,j) + dist(i-1,i)和d(i,i-1)=  min( d(i,i - 1),d(i - 1, j) + dist(j,i))

这两个式子看似互相独立,但是都影响着将来。


最后是dp的边界条件,初始肯定要有人走第一步,这个初始化一下。

第二个是i走到i后还要再让j走到最后一步。


#include 
using namespace std;
#define M 1010
typedef pair P;
#define f first
#define s second
#define INF 100000000

P date[M];
double dp[M][M];
double ans;
//bool vis[M];

//distance
double dist(int i, int j)
{
    double x = abs(date[i].f - date[j].f);
    double y = abs(date[i].s - date[j].s);

    return hypot(x, y);
}

int main()
{
    int n;

    while(scanf("%d", &n) != EOF)
    {
        for(int i = 1; i <= n; i++){
            scanf("%d%d", &date[i].f, &date[i].s);
        }

        for(int i = 0; i <= n; i++){
            for(int j = 0; j <= n; j++){
            dp[i][j] = INF;
            }
        }
       // memset(vis, 0, sizeof(vis));

       //edge
        dp[2][1] = dist(2, 1);
        ans = INF;
        for(int i = 3; i <= n; i++){
            for(int j = 1; j < i - 1; j++){
                dp[i][j] = dp[i - 1][j] + dist(i, i - 1);
                dp[i][i - 1] = min(dp[i][i - 1], dp[i - 1][j] + dist(j, i));
            }
        }

        //j‘s last step
        for(int i = 1; i < n; i++)
            ans = min(ans, dp[n][i] + dist(n, i));

        printf("%.2lf\n", ans);
    }

    return 0;
}


你可能感兴趣的:(算法竞赛入门经典紫书)