zoukankan      html  css  js  c++  java
  • zoj 3981 Balloon Robot

    https://vjudge.net/problem/ZOJ-3981

    题意:

    有m个座位,其中n个队伍坐在这些位置上,一个队伍一个座位。当一个队A了题之后,他们们会得到气球,假设他们在a时刻A题,但是在b时刻才得到气球,那么他们的不高兴值就会增加b - a。现在主办方安排了一个机器人发气球,机器人每时刻都会向右移动一个位置(当然是循环的),到了一个位置,如果这个位置上有队伍并且A了题没有得到气球,那么就会把气球发给这个队伍。现在给出每个队伍的位置和A题的情况,要求安排机器人的起始位置使得所有队伍的不开心值之和最小。

    思路:

    首先可以假设机器人在1位置,计算出每个题的气球需要等待的时间,然后接下来证明一个猜想,枚举的时间点必然是A题的时刻:

    假设在当前枚举的时刻t没有A题,那么在枚举到t+1时刻,那么必然所有的A题的等待时间会减少1,直到有A题的时刻之后,时间才会增加。

    首先把每个的等待时间排个序(求等待时间的时候,使用了二分法),之后顺序枚举

    公式 ans = min(sum + i * m - d[i] * q),因为前面的A题时刻在起点后移之后必定会从m - 1开始递减的,所以有加上i * m,然后全部的等待时间都会减少d[i],所以每一个都减去。

    总的时间复杂度为O(n)。

    代码:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <vector>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 int d[100005];
     8 int pos[100005];
     9 
    10 bool meet(long long k,int tmp,int m,int b)
    11 {
    12     long long ans = k * m + tmp;
    13 
    14     if (ans >= b) return true;
    15     else return false;
    16 }
    17 
    18 int main()
    19 {
    20     int t;
    21 
    22     scanf("%d",&t);
    23 
    24     while (t--)
    25     {
    26         int n,m,p;
    27 
    28         scanf("%d%d%d",&n,&m,&p);
    29 
    30         long long sum = 0;
    31 
    32         for (int i = 1;i <= n;i++)
    33             scanf("%d",&pos[i]);
    34 
    35         for (int i = 0;i < p;i++)
    36         {
    37             int a,b;
    38 
    39             scanf("%d%d",&a,&b);
    40 
    41             a = pos[a];
    42 
    43             long long l = 0,r = 1000000000;
    44 
    45             int tmp = a - 1;
    46 
    47             while (l < r - 1)
    48             {
    49                 long long mid = (l + r) >> 1;
    50 
    51                 if (meet(mid,tmp,m,b)) r = mid;
    52                 else l = mid + 1;
    53             }
    54 
    55             while (meet(r - 1,tmp,m,b)) r--;
    56 
    57             d[i] = r * m + tmp - b;
    58 
    59             sum += d[i];
    60 
    61             //printf("%d 233
    ",d[i]);
    62         }
    63 
    64         sort(d,d+p);
    65 
    66         long long ans = 1000000000000000;
    67 
    68         for (int i = 0;i < p;i++)
    69         {
    70             long long tmp = sum + (long long)i * m - (long long) p * d[i];
    71 
    72             ans = min(tmp,ans);
    73         }
    74 
    75         printf("%lld
    ",ans);
    76     }
    77 
    78     return 0;
    79 }
  • 相关阅读:
    PHP开发学习门户改版效果图投票
    怎样用js得到当前页面的url信息方法(JS获取当前网址信息)
    java 获取当期时间之前几小时的时间
    超人学院Hadoop大数据技术资源分享
    plsql导入一个目录下全部excel
    UML简单介绍
    Mod in math
    父母之爱子,则为之计深远是什么意思?_百度知道
    2014创客118新年大爬梯_活动行-国内最好的活动报名及售票平台!
    北京创客空间 BEIJING MAXPACE的小站
  • 原文地址:https://www.cnblogs.com/kickit/p/7994997.html
Copyright © 2011-2022 走看看