【贪心】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\n",aans);
82     }
83     return 0;
84 }
85 /*
86 //
87 
88 //
89 */
View Code

 

posted @ 2016-08-22 00:19  Cool639zhu  阅读(628)  评论(0编辑  收藏  举报