• 【贪心】Codeforces 704B & 705D Ant Man


    题目链接:

      http://codeforces.com/problemset/problem/704/B

    题目大意:

      给N个点,起点S终点T,每个点有X,A,B,C,D,根据I和J的X坐标可得I到J的距离计算公式:(题目描述的那个i<j有错!害我WA了好几次)

    • |xi - xj| + ci + bj seconds if x[j] < x[i].
    • |xi - xj| + di + aj seconds otherwise (x[j] > x[i]).

      求从起点到终点,经过N个点恰好一次的最短路。

    题目思路:

      【贪心】

      这题首先一看过去觉得像DP题,但是数据好大,一时不知道怎么做。

      我是先把每个点到其他点的距离算出来,然后一个一个往S到T中间插入点,用一个链表记录每个点到达的下一个点。

      如果把当前结点I插在J和K中间比插在其他区间更优就更新答案。

     1 //
     2 //by coolxxx
     3 //#include<bits/stdc++.h>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<string>
     7 #include<iomanip>
     8 #include<map>
     9 #include<memory.h>
    10 #include<time.h>
    11 #include<stdio.h>
    12 #include<stdlib.h>
    13 #include<string.h>
    14 //#include<stdbool.h>
    15 #include<math.h>
    16 #define min(a,b) ((a)<(b)?(a):(b))
    17 #define max(a,b) ((a)>(b)?(a):(b))
    18 #define abs(a) ((a)>0?(a):(-(a)))
    19 #define lowbit(a) (a&(-a))
    20 #define sqr(a) ((a)*(a))
    21 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))
    22 #define mem(a,b) memset(a,b,sizeof(a))
    23 #define eps (1e-8)
    24 #define J 10
    25 #define mod 1000000007
    26 #define MAX 0x7f7f7f7f
    27 #define PI 3.14159265358979323
    28 #define N 5004
    29 using namespace std;
    30 typedef long long LL;
    31 int cas,cass;
    32 int n,m,lll,ans;
    33 double anss;
    34 int pre[N],next[N];
    35 LL aans,sum;
    36 LL x[N],a[N],b[N],c[N],d[N];
    37 LL dis[N][N];
    38 int main()
    39 {
    40     #ifndef ONLINE_JUDGE
    41 //    freopen("1.txt","r",stdin);
    42 //    freopen("2.txt","w",stdout);
    43     #endif
    44     int i,j,k;
    45     int s,t,mark;
    46 //    for(scanf("%d",&cas);cas;cas--)
    47 //    for(scanf("%d",&cas),cass=1;cass<=cas;cass++)
    48 //    while(~scanf("%s",s+1))
    49     while(~scanf("%d",&n))
    50     {
    51         scanf("%d%d",&s,&t);
    52         for(i=1;i<=n;i++)scanf("%I64d",&x[i]);
    53         for(i=1;i<=n;i++)scanf("%I64d",&a[i]);
    54         for(i=1;i<=n;i++)scanf("%I64d",&b[i]);
    55         for(i=1;i<=n;i++)scanf("%I64d",&c[i]);
    56         for(i=1;i<=n;i++)scanf("%I64d",&d[i]);
    57         for(i=1;i<=n;i++)
    58         {
    59             for(j=1;j<=n;j++)
    60             {
    61                 if(i==j)continue;
    62                 if(x[j]<x[i])dis[i][j]=abs(x[i]-x[j])+c[i]+b[j];
    63                 else dis[i][j]=abs(x[i]-x[j])+d[i]+a[j];
    64             }
    65         }
    66         aans=dis[s][t];
    67         next[s]=t;
    68         for(i=1;i<=n;i++)
    69         {
    70             if(i==s ||i==t)continue;
    71             for(j=s,sum=1e18;j!=t;j=next[j])
    72             {
    73                 k=next[j];
    74                 if(dis[j][i]+dis[i][k]-dis[j][k]<sum)sum=dis[j][i]+dis[i][k]-dis[j][k],mark=j;
    75             }
    76             aans+=sum;
    77             j=mark;k=next[j];
    78             next[j]=i;
    79             next[i]=k;
    80         }
    81         printf("%I64d
    ",aans);
    82     }
    83     return 0;
    84 }
    85 /*
    86 //
    87 
    88 //
    89 */
    View Code
  • 相关阅读:
    实例化讲解RunLoop---IOS
    IOS中的SpringBoard
    Mac版OBS设置详解
    Swift学习Tip之Closures
    Swift中Array的Map
    IOS中的国际化(一)
    IOS,中获取系统内存占有率的方法
    IOS获取两个日期之间的时间间隔
    IOS中微信支、支付宝支付详解
    IOS中的正则表达式:NSRegularExpression
  • 原文地址:https://www.cnblogs.com/Coolxxx/p/5794100.html
Copyright © 2020-2023  润新知