1. 程式人生 > 實用技巧 >牛牛涼衣服

牛牛涼衣服

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 = \lceil\frac{a[i] - mid}{k - 1}\rceil \]

還要注意爆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 ;
}
/*
*/