zoukankan      html  css  js  c++  java
  • 紫书 例题 9-3 UVa 1347 ( 状态设计)

    首先做一个转化,这种转化很常见。
    题目里面讲要来回走一遍,所以就转化成两个从起点到终点,路径不重合
    那么很容易想到用f[i][j]表示第一个走到i,第二个人走到j还需要走的距离
    但是这里无法保证路径不重合,所以这里怎么设计状态很关键。
    我们设f[i][j]是1到max(i, j)全部走过,同时第一个在i,第二人在j,
    还需要走的距离,可以看出f[i][j] = f[j][i],所以我们可以规定i > j
    那么这么规定有什么好处呢?我们可以让两个人走的路径是1, 2, 3, 4……
    换句话说,当前是f[i][j],根据定义,1到i全部走过,接下来要走到第i+1个位置
    假设是第一个人走,也就是在i的这个人走,那么可以从f[i][j]转移到f[i+1][j]
    假设是第二个人走,也就是在j的这个人走,那么可以从f[i][j]转移到f[i+1][i](j到i+1,而规定前面的要大)
    dist[i][j]表示i到j的欧几里得距离
    边界是f[n-1][j] = dist[i][n] + dist[j][n]最后的时候肯定是两个人走到终点,我们要从终点逆推
    最终答案是d[2][1] + dist[2][1]。

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #define REP(i, a, b) for(int i = (a); i < (b); i++)
    using namespace std;
    
    const int MAXN = 55;
    double x[MAXN], y[MAXN], dist[MAXN][MAXN], d[MAXN][MAXN];
    
    int main()
    {
    	int n;
    	while(~scanf("%d", &n))
    	{
    		REP(i, 1, n + 1) scanf("%lf%lf", &x[i], &y[i]);
    		REP(i, 1, n + 1)
    			REP(j, 1, n + 1)
    				dist[i][j] = sqrt(pow(x[i]-x[j], 2) + pow(y[i]-y[j], 2));
    		
    		for(int i = 2; i <= n; i++)
    			REP(j, 1, i)
    			{
    				if(i == 2) d[i][j] = dist[1][2];
    				else d[i][j] = min(d[i+1][j] + dist[i][i+1], d[i+1][i] + dist[i+1][j]);
    			}
    		printf("%.2lf
    ", d[2][1] + dist[2][1]);
    	}
    	return 0;
    }
  • 相关阅读:
    奇数阶魔方问题
    《DSP using MATLAB》示例9.3
    《DSP using MATLAB》示例9.2
    《DSP using MATLAB》示例9.1
    找个目标很重要
    《DSP using MATLAB》示例Example 8.30
    《DSP using MATLAB》示例Example 8.29
    《DSP using MATLAB》示例Example 8.28
    《DSP using MATLAB》示例Example 8.27
    《DSP using MATLAB》示例Example 8.26
  • 原文地址:https://www.cnblogs.com/sugewud/p/9819459.html
Copyright © 2011-2022 走看看