牛牛涼衣服
阿新 • • 發佈:2020-07-17
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 ; } /* */