1 solutions

  • 1
    @ 2023-4-29 15:56:01

    明显是二分答案,用 llrr 来确定二分边界,写一个 check 函数来完成当前枚举的 llrr 的中间数 midmid 能否完成任务,最后输出 midmid 的最小值即可。

    check 函数是一个贪心,定义两个指针 llrr (注意与上文的 llrr 不同)指向数组的头和尾和一个变量 ss 记录需要的箱子数,让 rr 从后往前搜索,判断每次搜索到的 rrll 所在的值加起来是否小于当前的 midmid ,如果是则让 ll 指向下一个元素,无论是不是都要将 ss11 ,最后判断 sskk 的大小,如果 sks \geqslant k 则这次任务完成。

    时间复杂度 O(nlog2000001)O(n\log 2000001) ,即 O(n)O(n) ,对于这道题绰绰有余。

    #include<bits/stdc++.h>
    using namespace std;
    int a[100100],k,n,ans;
    bool check(int x){
    	int l = 1,s = 0;
    	for(int r = n;l <= r;r--){
    		if(l < r && a[l] + a[r] <= x){//l和r如果相等,l也不用加1
    			l++;
    			s++;
    		}
    		else s++;
    	}
    	if(s <= k) return 1;
    	return 0;
    }
    int main(){
    	cin>>n>>k;
    	for(int i = 1;i <= n;i++){
    		cin>>a[i]; 
    	}
    	int l = a[n],r = 2000001;//r不能太大
    	while(l < r){//二分查找
    		int mid = (l + r) / 2;
    		if(check(mid)){//判断
    			ans = mid;
    			r = mid;//这里r不能为mid-1而要为mid
    		}
    		else l = mid + 1;
    	}
    	cout<<ans;
    	return 0;
    }
    
    • 1

    Information

    ID
    7141
    Time
    2000ms
    Memory
    256MiB
    Difficulty
    4
    Tags
    # Submissions
    3
    Accepted
    1
    Uploaded By