zoukankan      html  css  js  c++  java
  • lightoj.1048.Conquering Keokradong(二分 + 贪心)

    Conquering Keokradong
    Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu

    Description

    This winter we are going on a trip to Bandorban. The main target is to climb up to the top of Keokradong. So, we will use a trail. The trail is a continuous marked footpath that goes from Bandorban to Keokradong.

    Part of the experience is also the route planning of the trip. We have a list of all possible campsites that we can use along the way and we want to do this trip so that we only stop K nights to camp. We also know in advance the distance between consecutive campsites and we are only allowed to camp at a campsite. Our goal is to plan the trip so that we minimize the maximum amount of walking done in a single day. In other words, if our trip involves 2 nights (3 days of walking), and we walk 9, 10, 5 miles on each day respectively, the cost (maximum amount of walking done in one day) is 10. Another schedule that involves walking 9, 6, 9 miles on each day has cost 9.

    Given the distances between N consecutive campsites of a trail and given the number of nights for your trip, K, your task is to devise a camping strategy for the specified trail such that it minimizes the maximum amount of walking done in a single day. Note that the first distance value given is the distance from our start-point of the trail to our 1st campsite, and the last distance value given is the distance from our Nth campsite to our end-point of the trail.

    Input

    Input starts with an integer T (≤ 200), denoting the number of test cases.

    Each case contains of two integers, the number of campsites, N (1 ≤ N ≤ 1000) and the number of nights of the trip, K (1 ≤ K ≤ min(N, 300)). The following N + 1 lines indicate the distance in miles between consecutive campsite locations. All the integers will be positive and less than10000.

    Output

    For each case of input you have to print the case number and the minimized cost as described above. Then print K+1 lines, each containing the amount of distance covered in ith day. As there can be many solutions, the primary target is to find the one which ensures that each day we have to walk some distance. For ties, print the one where the distance covered in first day is maximum, then the distance covered in second day is maximum and so on.

    Sample Input

    1

    4 3

    7

    2

    6

    4

    5

    Sample Output

    Case 1: 8

    7

    8

    4

    5

     
     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 const int inf = 0x3f3f3f3f ;
     5 int n , m ;
     6 int T ;
     7 int a[2000] ;
     8 int l , r ;
     9 
    10 bool solve (int mid)
    11 {
    12     int tmp = 0 , cnt = 0 ;
    13     for (int i = 0 ; i < n ; i ++) {
    14         tmp += a[i] ;
    15         if (tmp > mid) {
    16             tmp = a[i] ;
    17             cnt ++ ;
    18         }
    19     }
    20     cnt ++ ;
    21     return cnt > m ;
    22 }
    23 
    24 int main ()
    25 {
    26     //freopen ("a.txt" , "r" , stdin ) ;
    27     scanf ("%d" , &T) ;
    28     int cas = 1 ;
    29     while (T --) {
    30         scanf ("%d%d" , &n , &m ) ;
    31         n ++ ; m ++ ;
    32         l = - inf ;
    33         r = 0 ;
    34         for (int i = 0 ; i < n ; i ++) {
    35             scanf ("%d" , &a[i]) ;
    36             l = std::max (a[i] , l ) ;
    37             r += a[i] ;
    38         }
    39         while (l <= r) {
    40             int mid = ( l + r ) / 2 ;
    41             if (solve (mid) ) l = mid + 1 ;
    42             else r = mid - 1 ;
    43         }
    44         printf ("Case %d: %d
    " , cas ++ , l ) ;
    45         int sum = 0 ;
    46         int cnt = 0 ;
    47         for (int i = 0 ; i < n ; i ++) {
    48             sum += a[i] ;
    49             if (sum > l) {
    50                 printf ("%d
    " , sum - a[i]) ;
    51                 sum = a[i] ;
    52                 cnt ++ ;
    53             }
    54             if (m - cnt + i >= n) {
    55                 printf ("%d
    " , sum ) ;
    56                 for (int j = i + 1 ; j < n ; j ++) printf ("%d
    " , a[j]) ;
    57                 break ;
    58             }
    59         }
    60     }
    61     return 0 ;
    62 }
    View Code

    initial l = max{a[]} , r = sum {a[]} ;

    很明显我们要求的x肯定在[l,r]这个区间内。

    我们也能很容易求出:当组合后各个堆中最大的x已知时,至少需要走的天数 day。

    所以我们令mid = (l + r)/ 2 ; 并求出对应的 day,if day > (k + 1) , 说明x的值应在[mid + 1,r]上 ; else , 便在[l,mid - 1]上(ps:至于为什么day == k + 1是也定位在这一块,是因为我们想令day “minimize”)。

    而且因为我们所求的最后x,是指至少需要走的天数,所以很多情况下会比k + 1小,所以输出时应尽量让前面的a[i]相加贴近x,在最后到。。。就单个输出啊a[i]来补到k+1个。

  • 相关阅读:
    深入理解关系型数据库的数据水平切分和垂直切分
    数据库Sharding的基本思想和切分策略
    Mycat 设置全局序列号
    Spring MVC异常统一处理
    spring配置文件中bean标签
    浅析VO、DTO、DO、PO的概念、区别和用处
    CentOS7.0安装Nginx 1.7.4
    大数据的四大特点
    CentOS 7 上安装 redis3.2.3安装与配置
    CentOS7下安装MySQL5.7安装与配置(YUM)
  • 原文地址:https://www.cnblogs.com/get-an-AC-everyday/p/4523159.html
Copyright © 2011-2022 走看看