POJ 3104 二分

题意

传送门 POJ 3104

这道题的教训是要考虑好复杂度和数据范围。

最先想到贪心法,优先队列每次处理当前未晾干衣服水分的最大值,TLE,因为极端情况 O ( m a x { a i } ) O(max\{a_{i}\}) O(max{ai})

考虑二分法, O ( n l o g ( m a x { a i } ) ) O(nlog(max\{a_{i}\})) O(nlog(max{ai})),搜索时间值,所有衣服都当做自然烘干叠加射线烘干(速度 K − 1 K-1 K1)来处理,当水分大于自然烘干值,则必须使用射线,累加使用射线的次数(时间)即可。极端情况,射线次数累加值 i n t int int 会溢出,需要使用 l o n g   l o n g long\ long long long 或者预处理。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#define min(a,b)    (((a) < (b)) ? (a) : (b))
#define max(a,b)    (((a) > (b)) ? (a) : (b))
#define abs(x)    ((x) < 0 ? -(x) : (x))
#define INF 0x3f3f3f3f
#define delta 0.85
#define eps 1e-3
#define PI 3.14159265358979323846
#define MAX_N 100005
using namespace std;
int N, K;
int A[MAX_N];

bool C(int t){
	int cnt = 0;
	for(int i = 0; i < N; i++){
		cnt += (A[i] - t <= 0 ? 0 : (A[i] - t - 1) / K + 1);
		if(cnt > t) return false;
	}
	return true;
}


int main(){
	while(~scanf("%d", &N)){
		for(int i = 0; i < N; i++) scanf("%d", A + i);
		scanf("%d", &K); --K;
		if(K == 0){
			printf("%d\n", *max_element(A, A + N));
			continue;
		}
		int left = 0, right = INF;
		while(right - left > 1){
			int mid = (left + right) >> 1;
			if(C(mid)) right = mid;
			else left = mid;
		}
		printf("%d\n", right);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值