基本的なアプリケーションのバイナリ解答クラスの質問

I.はじめ知識

我々は半分の回答簡単にバイナリ検索を説明すると言う前に、半分は、多くの時間を節約、あなたは正解位置を見つけるまで、彼は半分にするたびに、問題の規模を、私たちを助けることができる、非常に良いアイデアです多くの場合、彼は私たちを助けることができます質問、あなたはこのシーケンス内の番号を探しているなら、これは、非常に基本的な二分法の問題であり、彼はソートまず、右へ左エンドのための開始点を設定するよう中旬場合は、以下の目標よりも半ばを計算するために、各サイクルが残されますミッド+ 1への移行半ば以上の目標は、右=半ばには、そのことについては、我々は注意を払う必要があります作成する場合は、以下半ば+ 1に移動する時間よりも、またはそれに左右の隣接場合は、右の位置は正の解であるが、中旬以降サイクルダウン自動丸め、結果を終了していません。バイナリ検索は、独自に設定したサイクル数を制限することを選択できアルゴリズムは2の増加した電力の大きさに基づいているので、単純サイクル60回を設定し、あなたは2を確保することができ、L == rの境界条件を選択することができることに注意してください60電源内のデータを見つけることができます。
ここでは、単純な二分探索コードがあります

int target;
while(l!=r)
{
mid=(l+r)/2;
if(target<=mid)r=mid;
else l=mid+1;
}

バイナリ検索を持って、私たちは実際には、答えの半分は単なる抽象モデルで、半分の答えを見ていき、その意味は、範囲内のいくつかの整数のためである、条件を満たしたり、条件を満たしていない、と単調に応じて各数モデルの抽象的モデルを表すために、我々は、2つの点を介して第1の条件を満たす数を見つけるコンピュータに条件を満たすことができる(連続的な期間は最初後満たされを満足していない)か否かをtrueとfalseまたは0であってもよく、1見出されます最初の出会いの期間000011111の単調なシーケンスのような形をしている値は、最初の1で見つかったが、我々はちょうど同じ裁判官の正しいか間違っているの半ばではありません、我々はここに注意を払うに必要な、1ではありません中旬には、我々が行ってきましたので、それの特定の右にある最初の0である場合、L = MIDは、彼が前に最初のものだったと我々は維持したいので、可能性があることを含めているミッド+ 1、R =ミッド境界は、実際の状況に応じて調整する必要があります。
実際にはバイナリ検索も対処するためにこのモデルを使用することができ、我々は答えは1または0、質問へのバイナリの答えに変換され、ターゲットに等しいより大きい場合、ターゲットに等しいより大きい最小の数に問題を見つけ
、それがためであるよりも大きくなければなりません注意を払うのキーワードに我々が持っているすべての、タイトルはこの意味を暗示している場合、通常の半分にこの質問を解決するために使用することができますされ、対象の最小値または特定の少数の最大数に等しい
という事実を我々はまだいくつかの特別なボーダーに対処する必要があります全体のシーケンスは0または1をしている場合、実際には、半分の答えの精度を確保するために状況は、我々はサイクルが正常に完了した国境問題に対処できることを保証するために、開始前に、代入の終了後に必要な、アンサーモデルの半分が完成しなければなりません。
しかし、このモデルのために、直接問題の二分法の多くは非常に微妙になりますので、我々はこの問題に対する自分自身の変換を見つける必要があり、彼は問題を解決始まる適用することは困難です。ここではいくつかの例では簡単の外観です

実用化

1. ここに画像を挿入説明
この質問はよく私たちは木を切り倒すのに最も適した場所、実際のこの質問を見つけなければならないので、私たちは、できるだけ木を伐採の前提条件を満たすように半分の条件判定を持つターゲット番号を持つように質問をされた意味を理解されたいです木を伐採する条件を満たすように、この位置に十分であることは明らかである、我々は最初のものの最大数を見つけ、その後、正しい答えを見つけるためにのみ判定機能により、半分を起動し
、次のようにコードすることです

#include<bits/stdc++.h>
using namespace std;
long long n,m,a[10000004],tmp,l,r,ans,mid;
bool check(long long x){
    for(long long i=1;i<=n;i++)
        if(x<a[i])tmp+=a[i]-x;
    return m<=tmp;//骚写法,如果满足条件则返回1 
}
int main(){
    cin>>n>>m;
    for(long long i=1;i<=n;i++)cin>>a[i],r=r>a[i]?r:a[i];//h找到最大值
    while(l<=r){
         mid=(l+r)>>1;tmp=0;
        if(check(mid))l=(ans=mid)+1; 
        else r=mid-1;
    }
    cout<<ans;
    return 0;
}

この質問はもう少し複雑次の質問では、より明白な、外観を表します。
ここに画像を挿入説明
私たちは、ロープをカットしたい、ターゲットはk個のセクションに分割され、各文字列はk個のセグメントの有限個に分割することができ、各セグメントは、最初にすべてのこの質問は、浮動小数点エラーを、私たち最初避けるために、2つのだけ小数点以下の桁数で、問うまで到達することができますすべてのデータは、この問題を解決することができ100、加えて、最後の100を乗じて、我々は条件、それ以上に複雑ほんの少しを決定するために以下の2点でこの質問を見に来て、実際には、問題は、各セグメントは限りk個に分割することができた場合もしくは複数のKということです段落の
コードは、また、彼は、そして上記のように(100×100に加えていないコードが、実際には、これはいくつかの浮動小数点エラーが発生することがあります)ことをロープの各部分は/段落の長さの電流要件は、セグメントに分割されたものにだけ注意を払う非常に簡単です

#include<bits/stdc++.h>
using namespace std;
int n,k;
double a[10005],l,r,mid;
char s[100];
inline bool check(double x)
{
    int tot=0;
    for(int i=1;i<=n;i++)tot+=floor(a[i]/x);
    return tot>=k;
}
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)scanf("%lf",&a[i]),r+=a[i];
    while(r-l>1e-4)
    {
        mid=(l+r)/2;
        if(check(mid))l=mid;
        else r=mid;
    }
    printf("%.2lf",l); 
    return 0;

実際には、上記の二つの質問は、最も明白な二分法の問題の中で、このブログはまた、唯一のいくつかの単純な二分法の質問を記録している自分の初心者2つの部門では、以下の貪欲組み合わせ1で見納めに遭遇し、二つのサブ問題
の主題を見て
ここに画像を挿入説明
、この時の私の最初の一見質問、それは彼が二分法を解決するために使用できることを想像することは困難であり、私はこの問題は見ていることを知って、裁判官に適切な条件を見つけられませんでした
ここに画像を挿入説明
、これは彼の単純化したモデルである必要があり、問題は貪欲、意見を取ることができていることを確認することは容易であるが、意見を分割することはできません私は質問の裁判官に上記の条件を考えるようセクションでは、各セグメントが少ないMを満たすことができないセグメントの数よりも最後の1つの配列111.111億にX発見されたとき、我々は唯一の半ば「割り当てとの国境の一部を変更する必要がありますする必要がありますケースの問題が解決され、

#include<bits/stdc++.h>
using namespace std;
int n,m,a[100005],l,r,mid,ans;
inline bool check(int x)
{
    int tot=0,num=0;
    for(int i=1;i<=n;i++)
    {
        if(tot+a[i]<=x)tot+=a[i];
        else tot=a[i],num++;
    }
    return num>=m;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]),l=max(l,a[i]),r+=a[i];
    while(l<=r)
    {
        mid=l+r>>1;
        if(check(mid))l=mid+1;
        else r=mid-1;
    }
    cout<<l;
    return 0;
}

このいくつかの問題二分行われ、私はその半分が実際に強い汎用的な性質を持って実現し、これらは、裁判官の条件トピック以来、ちょうど最も基本的な二分法は、多くの問題を解決するために二分問題に変換することができますがありますターゲットの最大数に等しいか又はそれ以下、特定の数以上関連の半分よりもよりもより微妙な、我々は、経験を積む最小数を満たさなければならないので、他を解決するために、より多くの知識を組み込むことも大きいです。

公開された48元の記事 ウォン称賛17 ビュー4458

おすすめ

転載: blog.csdn.net/weixin_45757507/article/details/104430600