他在x轴上的坐标只有20个这也就意味着我们可以暴力枚举。
他的精度是小数点后后两位,我们就直接把纵坐标直接乘上基数100这样就消除了精度的问题。
那么dp方程就很简单了
d
p
[
i
]
[
j
]
=
m
i
n
(
d
p
[
i
]
[
j
]
,
d
p
[
i
−
1
]
[
k
]
+
d
i
s
(
w
a
l
l
[
i
−
1
]
[
0
]
,
k
/
100.0
,
w
a
l
l
[
i
]
[
0
]
,
j
/
100.0
)
)
;
dp[i][j]=min(dp[i][j],dp[i-1][k]+dis(wall[i-1][0],k/100.0,wall[i][0],j/100.0));
dp[i][j]=min(dp[i][j],dp[i−1][k]+dis(wall[i−1][0],k/100.0,wall[i][0],j/100.0));
ac code
//god with me
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
double dp[25][2005];
double wall[25][5];
double dis(double a1,double a2,double b1,double b2)
{
return sqrt((a1-b1)*(a1-b1)+(a2-b2)*(a2-b2));
}
void solve()
{
memset(dp,0x7f,sizeof(dp));
int n;
for(int i=0;i<=2000;i++)dp[0][i]=0;
cin>>n;
for(int i=1;i<=4;i++)
{
wall[0][i]=5;
wall[n+1][i]=5;
}
wall[0][0]=0;
wall[n+1][0]=10;
for(int i=1;i<=n;i++)
{
for(int j=0;j<=4;j++)cin>>wall[i][j];
}
for(int i=1;i<=n+1;i++)
{
for(int j=0;j<=1000;j++)
{
if((j/100.0>=wall[i][1]&&j/100.0<=wall[i][2])||(j/100.0>=wall[i][3]&&j/100.0<=wall[i][4]))
for(int k=0;k<=1000;k++)
{
if((k/100.0>=wall[i-1][1]&&k/100.0<=wall[i-1][2])||(k/100.0>=wall[i-1][3]&&k/100.0<=wall[i-1][4]))
{
dp[i][j]=min(dp[i][j],dp[i-1][k]+dis(wall[i-1][0],k/100.0,wall[i][0],j/100.0));
}
}
}
}
printf("%.2f",dp[n+1][500]);
}
signed main() {
int T=1;
for(int i=1;i<=T;i++)
{
solve();
}
return 0;
}