2 条题解

  • 1
    @ 2023-11-28 22:41:19

    贪心,尽可能充分利用每只独木舟。这套题贪心策略很好想,但实现起来还是挺有意思的。

    原来我的思路是先对体重数组从大到小排序,然后两层循环逐个配对,配对成功则标记筛出,时间复杂度为O(n^2),我自信满满地提交,结果顺理成章地50 Time Exceeded了。

    要想通过此题,那么时间复杂度就得是O(n),也就相当于只能使用一次遍历。那么怎样才能一次遍历解决问题呢?每个元素只可以被访问一次,但逐个配对又需要n次,能否只执行一次配对呢?随后灵光一闪,对于有序数组而言,若想配对,那就得是数组左边和右边相对,我们可以使用栈来存储体重,在遍历的过程中,如果空栈或者无法与栈顶元素(由于数组是有序的,遍历是有序的,那么栈也是有序的,如果栈顶都无法配对成功,就更不必考虑栈内其他元素了)配对就入栈,入栈即使用了一个新的独木舟,则计数。若配对成功,则弹出栈顶。如此,一次遍历便可解决。提交,100 Accepted

    #include<iostream>
    #include<algorithm>
    using namespace std;
    int a[30001];//存储体重
    int b[30001]={0};//初始化栈
    int  k=0;//栈顶指针
    bool cmp(int x,int y){//sort比较器
    	return x>y;
    }
    int main(){
    	int w,n,ans=0;
    	cin>>w>>n;
    	for(int i=1;i<=n;i++) cin>>a[i];
    	sort(a+1,a+n+1,cmp);//体重从大到小排序
    	a[0]=200;//设置前导元素,以保证空栈时程序正常运行
    	for(int i=1;i<=n;i++){
    		if(a[i]+a[b[k]]<=w) k--;//若与栈顶体重之和在最大载重量内,则弹出栈顶
    		else b[++k]=i,ans++;//入栈
    	}
    	cout<<ans;
    	return 0;
    }
    

信息

ID
444
时间
1000ms
内存
256MiB
难度
8
标签
递交数
133
已通过
24
上传者