20行のコードAC_演習8-1 Bin Packing UVA-1149(貪欲+単純なバイナリ分析)

効率的な表現のための刺激的な使用の少ないコード


題名

NアイテムのZhonglian L1とバックパックMの容量を考慮して、各バックパックは最大2つのアイテムを保持する必要があり、すべてのアイテムを保持するのに必要なバックパックの数。

問題解決プロセス

バックパックとの最初の接触。

元のアイデアは、降順で並べ替え、最大値からトラバースし、バックパックにパックできる2つのオブジェクトが見つかるまでiの後にjからトラバースします。見つからない場合、最大値は個別にパックされます。時間の複雑さはO(n ^ 2)、タイムアウト、複雑です。

インターネットを検索した後、より最適化されたアイデアは次のとおりです。昇順で並べ替え、iの最小値からトラバース、jの最大値からトラバース。2つの合計が条件を満たす場合はパックし、そうでない場合は大きい値を個別にパックします。

それで私は考え始めました、なぜソートを調整するだけで、時間の複雑さとコードの複雑さがそれほど違うのですか?

ブレーンストーミングの後、次の結論に達しました:
降順で並べ替えると、各トラバーサルの後に、条件を満たさない人はスキップされ、判断のサイクルに何度も参加します。
また、昇順で並べ替えると、条件が満たされているかどうかに関係なく、すべてのトラバーサルが、処理されるため、効率が大幅に向上します(単純な二分法、分割統治の原則)。
また、トラバースするたびに後者が対応する処理を実行するため、判断がシーケンスの両端で制御されるたびに、アイデアがはるかに単純になります。

質問のACは、多くの場合、単一の思考の範囲内にあることがわかります。より柔軟に考えると、問題をより速くより適切に解決できます

以下のコードを貼り付けます。

N <= 10 ^ 5ですが、a [100005]に設定されたアレイはバーストすることに注意してください。最後に、成功したACである[100010]に変更されました。それもちょっとしたトリックです。

#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; } 

おすすめ

転載: blog.csdn.net/weixin_43899069/article/details/108294389