牛牛凉衣服

https://ac.nowcoder.com/acm/contest/6220/C

牛牛有n件带水的衣服,干燥衣服有两种方式。
一、是用烘干机,可以每分钟烤干衣服的k滴水。
二、是自然烘干,每分钟衣服会自然烘干1滴水。
烘干机比较小,每次只能放进一件衣服。
注意,使用烘干机的时候,其他衣服仍然可以保持自然烘干状态,现在牛牛想知道最少要多少时间可以把衣服全烘干。

本来想的贪心,代码如下,

class Solution {
public:
    /**
     * 计算最少要多少时间可以把所有的衣服全烘干
     * @param n int整型 n件衣服
     * @param a int整型vector n件衣服所含水量数组
     * @param k int整型 烘干机1分钟可以烘干的水量
     * @return int整型
     */
    int solve(int n, vector<int>& a, int k) {
        // write code here
        sort(a.begin() , a.end()) ;
        int t = 0 ;
        for(int i = a.size() - 1 ;i >= 0 ;i --) {
            int res = a[i] - t ;
            if(res <= 0) continue ;
            res = (res / k) + (res % k ? 1 : 0) ;
            t += res ;
        }
        return t ;
    }
};

对于上述代码的贪心错误理解:
把所有的数排序一下, 然后从大到算一下时间。
我这样计算的结果就是可能存在一个x , 他x % k = y , 这个y可能是1,也可能是2,甚至别的,那么这几滴水也被用做了一分钟,何不把他自然烘干,节省时间, 将这个一分钟的时间给其他满足x >= k的来用用 , 这样这个一分钟完全去掉了k滴水。
但是具体对两者分配不知,假设每个物品自然烘干和机器烘干的时间分别是x1 , x2 , 二分时间mid
在这个条件下,每次二分的时候,自然烘干一定是满足条件的,但是机器烘干不一定满足条件,我只需要判断机器烘干就行了

[x1 + x2 = mid ]

[a[i] = x2 * k + x1 ]

[=>x2 = lceilfrac{a[i] - mid}{k - 1} ceil ]

还要注意爆int

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <map>
#include <list>
#include <queue>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <stack>
#include <set>
#pragma GCC optimize(3 , "Ofast" , "inline")
using namespace std ;
#define ios ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define x first
#define y second
typedef long long ll ;
const double esp = 1e-6 , pi = acos(-1) ;
typedef pair<int , int> PII ;
const int N = 1e6 + 10 , INF = 0x3f3f3f3f , mod = 1e9 + 7;
ll in()
{
  ll x = 0 , f = 1 ;
  char ch = getchar() ;
  while(!isdigit(ch)) {if(ch == '-') f = -1 ; ch = getchar() ;}
  while(isdigit(ch)) x = x * 10 + ch - 48 , ch = getchar() ;
  return x * f ;
}
bool check(int n , vector<int> &a , int k , ll mid){
  ll sum = 0 ;
  k -- ;
  if(!k) return a[n - 1] ;
  for(int i = 0 ;i < n ;i ++ ) {
    if(a[i] > mid) {
      ll t = a[i] - mid ;
      sum += t / k + (t % k ? 1 : 0) ;
    }
  }
  return sum <= mid ;
}
int solve(int n, vector<int>& a, int k) {
    // write code here
    int l = 0 , r = INF ;
    while(l < r) {
      int mid = l + r >> 1 ;
      if(check(n , a , k , mid)) r = mid ;
      else l = mid + 1 ;
    }
    return r ;
}
int main()
{
  int n = in() ;
  vector<int> v(n) ;
  for(int i = 0 ;i < n ;i ++) v[i] = in() ;
  int k = in() ;
  cout << solve(n , v , k) << endl ;
  return 0 ;
}
/*
*/

原文地址:https://www.cnblogs.com/spnooyseed/p/13329520.html