20行代码AC_ 习题8-1 Bin Packing UVA - 1149(贪心+简单二分解析)
勵(lì)志用少的代碼做高效表達(dá)
題意
給定N個(gè)物品的中聯(lián)L1,背包的容量M,同時(shí)要求每個(gè)背包最多裝兩個(gè)物品,求至少要多少個(gè)背包才能裝下所有的物品。
解題過(guò)程
第一次接觸背包類問(wèn)題。
最初的思路是降序排序,i從最大值遍歷,j從i后遍歷,直到找到可以裝在一個(gè)背包里的兩個(gè)物體,若無(wú),則把最大值單獨(dú)裝包。時(shí)間復(fù)雜度為O(n^2),超時(shí)且復(fù)雜。
網(wǎng)搜后,發(fā)現(xiàn)更優(yōu)化的思路是:升序排序,從i最小的值遍歷,j從最大的值遍歷,若二者和滿足條件,則裝包, 反之將較大值單獨(dú)裝包。
于是我陷入了思考, 為什么只是將排序調(diào)整一下,時(shí)間復(fù)雜度和代碼復(fù)雜度大不相同呢?
經(jīng)過(guò)腦暴,我得到了以下結(jié)論:
如果降序排序,每遍歷一次,不符合條件者會(huì)被跳過(guò),進(jìn)而參與一次又一次的循環(huán)判斷;
而升序排序后,每遍歷一次,無(wú)論是否符合條件,都會(huì)被處理,因此效率大大提高(簡(jiǎn)單二分的原理,分而治之)。
也正因后者每次遍歷都會(huì)做相應(yīng)的處理,因此每次判斷都會(huì)控制在數(shù)列的兩端,思路就會(huì)簡(jiǎn)單很多。
可見(jiàn),一道題的AC與否往往在一念之間,如果靈活一些思考,或許會(huì)更快更好的解決問(wèn)題。
下面貼代碼。
需要注意的是,雖然N<=10^5, 但數(shù)組設(shè)為a[100005]會(huì)爆掉。 最后改成了a[100010],成功AC。也算是一個(gè)小技巧。
#include<bits/stdc++.h> using namespace std; int a[100010]; int main() {ios::sync_with_stdio(false);int T; cin>>T; while(T--) {int n, num; cin>>n>>num;for(int i = 0; i < n; i++) cin>>a[i];sort(a, a+n);int i = 0, j = n-1, sum = 0;while(i <= j) {if(i == j) { sum++; break; } if(a[i]+a[j] <= num) { i++; j--; sum++; } else { j--; sum++; }}cout << sum << endl << (T?"\n":"");} return 0; }總結(jié)
以上是生活随笔為你收集整理的20行代码AC_ 习题8-1 Bin Packing UVA - 1149(贪心+简单二分解析)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 17行代码AC_51Nod - 2133
- 下一篇: 15行代码AC——ZOJ - 4118