P1523 여행사 약식

제목
중국어 문제는 이해하기 쉽지만 잘 풀지 못해, 짜증나!!!문제풀이를 보고 서쪽에서 동쪽으로 가는 것과 동쪽에서 서쪽으로 가는 것은 서쪽에서 서쪽으로 가는 것으로 볼 수 있다. 우리가 한 점에 가서 다른 점으로 갈 때 자연스럽게 dp가 생각난다. 왜냐하면 이 점에서 다른 점으로 가는 것은 두 가지 길 중 하나를 선택해서 가는 것이기 때문이다. dp[i][j]는 첫 번째 길이 i로 가고 두 번째 길이 j로 가기 때문에 j>i를 규정하면 방정식을 옮길 수 있다.
 dp[i][j+1]=min(dp[i][j+1],dp[i][j]+dis(j,j+1));//         j+1
 dp[j][j+1]=min(dp[j][j+1],dp[i][j]+dis(i,j+1));//         j+1,           ,     dp[j][j+1]。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define ms(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x & -x
#define fi first
#define se second
#define bug cout<
#define IOS ios::sync_with_stdio(false), cin.tie(0),cout.tie(0)
using namespace std;
const int maxn = 1e3 + 5;
const int maxm = 1.5e5+50;
const double eps = 1e-7;
const double inf = 0x3f3f3f3f;
const double  lnf  = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
const  double pi=3.141592653589;
struct node
{
    double l,r;
}a[maxn];
double dp[maxn][maxn],b[maxn];
bool cmp(node A,node B)
{
    return A.l<B.l;
}
double dis(int x,int y)
{
    return sqrt((a[x].l-a[y].l)*(a[x].l-a[y].l)+(a[x].r-a[y].r)*(a[x].r-a[y].r));
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lf%lf",&a[i].l,&a[i].r);
    }
    ms(dp,lnf);
    sort(a+1,a+1+n,cmp);
    dp[1][2]=dis(1,2);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            dp[i][j]=1e30;
        }
    }
    dp[1][2]=dis(1,2);
    for(int i=1;i<=n;i++)
    {
        for(int j=i+1;j<=n;j++)
        {
            dp[i][j+1]=min(dp[i][j+1],dp[i][j]+dis(j,j+1));
            dp[j][j+1]=min(dp[j][j+1],dp[i][j]+dis(i,j+1));
        }
    }
    double ans=1e30;
    for(int i=3;i<=n;i++)
    {
        ans=min(ans,dp[i][n]+dis(i,n));
    }
    printf("%.2lf
"
,ans); return 0; }

좋은 웹페이지 즐겨찾기