1 solutions

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

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

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

    时间复杂度 O(nlog⁡2000001)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