zoukankan      html  css  js  c++  java
  • 洛谷P1315 观光公交

    SB贪心......暴露了我代码能力巨弱的本质。

    题面

    解:首先我们应该想到DP(但是我想到了贪心......)

    然后分析题目本质,每个点有个限制,最早开走时间不得早于最晚上车时间。

    然后我们就可以把每个人看做都在那个时间上车。

    然后我们发现,对一个地方使用加速,会影响它后面一段区间。

    然后就有个暴力·雏形是枚举在某个点用加速,看它能够减少的时间,取最大的那个用。

    然后看一眼数据范围,大概是n²,可以过,只要你每次找到收益最大的点是O(n)即可。

    然后发现好难写,细节巨多无比......一直觉得这个算法是错的,因为只有一个想法,根本无法转成代码实现。

    然后肝了好久,受不了了,去看题解,发现我TM想的是正解,只是不会实现......

    代码实现:

    固定数组:limit,up,down,sum,分别表示最晚上车时间,上车人数,下车人数,down的前缀和。

    变化数组:dis,to,to_lar,now,influ,分别表示所用时间(D),最远能影响到的位置,这条影响链上最多能承受减去的时间,抵达这里的时间,这里修改会影响的人数。

    大部分可变数组都倒序求出,now是正序求出。

    然后试一下某hack数据:

    4 5 1
    3 0 2

    0 1 2
    0 1 4
    0 1 4
    0 1 4
    0 1 4       ans = 18

     1 #define wwx AK_IOI 
     2 
     3 #include <cstdio>
     4 #include <algorithm>
     5 
     6 const int N = 1010, INF = 0x7f7f7f7f, M = 10010;
     7 
     8 struct Custom {
     9     int t, A, B;
    10 }a[M];
    11 
    12 int n, m, k, dis[N], limit[N], to[N], now[N], up[N], down[N], sum[N], influ[N], to_lar[N];
    13 
    14 int main() {
    15     scanf("%d%d%d", &n, &m, &k);
    16     for(int i = 1; i < n; i++) {
    17         scanf("%d", &dis[i]);
    18     }
    19     for(int i = 1; i <= m; i++) {
    20         scanf("%d%d%d", &a[i].t, &a[i].A, &a[i].B);
    21         limit[a[i].A] = std::max(limit[a[i].A], a[i].t);
    22         up[a[i].A]++;
    23         down[a[i].B]++;
    24     }
    25     sum[1] = down[1];
    26     for(int i = 2; i <= n; i++) {
    27         limit[i] = std::max(limit[i], limit[i - 1]);
    28         sum[i] = sum[i - 1] + down[i];
    29     }
    30     // get limit sum up down 
    31     
    32     while(k) {
    33         now[1] = 0;
    34         for(int i = 2; i <= n; i++) {
    35             now[i] = std::max(now[i - 1], limit[i - 1]) + dis[i - 1];
    36         }
    37         int large = -1, pos = -1;
    38         to[n] = n - 1; 
    39         to_lar[n] = INF;
    40         for(int i = n - 1; i >= 1; i--) {
    41             if(now[i + 1] > limit[i + 1]) {
    42                 to[i] = to[i + 1];
    43                 to_lar[i] = std::min(to_lar[i + 1], now[i + 1] - limit[i + 1]);
    44                 //to_lar[i] = std::min(to_lar[i], dis[i]);  <- ERROR 
    45             }
    46             else {
    47                 to[i] = i;
    48                 to_lar[i] = INF; 
    49             }
    50             influ[i] = sum[to[i] + 1] - sum[i];
    51             //printf("influ : %d  %d  
    ", i, influ[i]);
    52             if(influ[i] > large && to_lar[i] && dis[i]) { 
    53                 large = influ[i];
    54                 pos = i;
    55             }
    56         }
    57         if(to_lar[pos] == 0) {
    58             break;
    59         }
    60         to_lar[pos] = std::min(to_lar[pos], dis[pos]);
    61         dis[pos] -= std::min(to_lar[pos], k);
    62         k -= std::min(to_lar[pos], k);
    63         //printf("pos = %d  to[] = %d  lar = %d 
    ", pos, to[pos], to_lar[pos]);
    64     }
    65     
    66     now[1] = 0;
    67     for(int i = 2; i <= n; i++) {
    68         now[i] = std::max(now[i - 1], limit[i - 1]) + dis[i - 1];
    69     }
    70     
    71     int ans = 0;
    72     for(int i = 1; i <= m; i++) {
    73         ans += now[a[i].B] - a[i].t;
    74     }
    75     
    76     printf("%d", ans);
    77     return 0;
    78 }
    AC代码

  • 相关阅读:
    ASP.NET Core 进程内(InProcess)托管
    ASP.NET Core 中的 Main 方法
    ASP.NET Core Web 项目文件
    5)
    4)
    单词
    html5单词
    3)
    2)
    1)
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/9803519.html
Copyright © 2011-2022 走看看