【动态规划dp】青蛙的烦恼

青蛙的烦恼(frog) 原文:https://blog.csdn.net/xyc1719/article/details/79844952 
【题目描述】
池塘中有 n 片荷叶恰好围成了一个凸多边形,有一只小青蛙恰好站在 1 号荷叶上,小青蛙想通过
最短的路程遍历所有的荷叶(经过一个荷叶一次且仅一次),小青蛙可以从一片荷叶上跳到另外任意一
片荷叶上。
【输入格式】
第一行为整数 n,荷叶的数量。
接下来 n 行,每行两个实数,为 n 个多边形的顶点坐标,按照顺时针方向给出。保证不会爆 double。
【输出格式】
遍历所有荷叶最短路程,请保留 3 位小数。
【输入样例】
4
50.0 1.0
5.0 1.0
0.0 0.0
45.0 0.0
【输出样例】
50.211
【数据范围】
对于所有数据,0< n<=720

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;

const int maxn=800;
const int inf=0x3f3f3f3f;

struct node
{
    double a,b;
}nn[maxn];

double f[maxn][maxn][2],dist[maxn][maxn];

double dis(node x,node y)
{
    return sqrt((x.a-y.a)*(x.a-y.a)+(x.b-y.b)*(x.b-y.b));
}

double recu(int i,int j,int k)
{
    if(i==j) return 0.0;
    if(f[i][j][k]==-1)
    {
        if(k==0) f[i][j][0]=min(recu(i+1,j,0)+dist[i][i+1],recu(i+1,j,1)+dist[i][j]);
        else if(k==1) f[i][j][1]=min(recu(i,j-1,1)+dist[j][j-1],recu(i,j-1,0)+dist[i][j]);
    }
    return f[i][j][k];
}

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%lf%lf",&nn[i].a,&nn[i].b);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
             dist[i][j]=dist[j][i]=dis(nn[i],nn[j]);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            for(int k=0;k<=1;k++)
                f[i][j][k]=-1;
    recu(1,n,0);
    printf("%.3lf",f[1][n][0]);
    return 0;
} 

猜你喜欢

转载自www.cnblogs.com/qqshiacm/p/10691584.html