Luogu - 最大のP1018製品 - 問題への解決策

オリジナル:Hのttps://www.luogu.org/problemnew/solution/P1018ページ= 7?

 

トピック:P1019 [製品]最大


 

はじめに:

  • この問題に対するポジティブなソリューションは、理論的にDP、しかしであると言われているので、プライベートデータは、あまりにも多くの水ではなく、使用するにはあまりにも難しい暴力

全体的なアイデア:

  1. それぞれがセグメント化されたか否かのフラグ(接続用、0分割)を用いてBアレイ。
  2. Bはnext_permutationのSTLを使用して、様々な置換(すなわち、暴力列挙それぞれの場合)を取得します。
  3. 大規模なデータの問題として、そう各部門の最終結果の高精度計算を使用し、最大値を見つけること。

 

next_permutation機能:

  • つまり、ある要求STL 完全なアレイ機能、それ以外の場合は、配列のすべて見つけることができません(このように構成され、それは方法に関連するグループ生成)通常通り、next_permutationをソート、2つのパラメータは、それぞれ存在する、昇順でなければならないアレイを尋ねますこれは、最初のアドレス、アレイの終了アドレスであり、ブール量を返し、すなわち、次の完全な配列は、次いで、1つの2 3の構成として、指定された配列にtrueを返し、次の配列できるか否かを判断します132です。

 

コードの場合:

#include <アルゴリズム> // 使用next_permutation呼び出す必要ヘッダ 
の#include <cstdioを>   // C言語読み取る出力 
する#include <CStringの>   // 高精度の加工文字列を使用する必要

使用して 名前空間はstdを、

構造体 BigN {   // 精度(すなわち、大整数)計算
    INT NUM [ 1001 ] = { 0 }、lenの;
    BigN(CHAR S [])   // 大きな整数割り当ての新しい定義のコンストラクタ
    {
        LEN = STRLEN(S)。
        INT I = len- 1 ; I> = 0 ; i-- 
            NUM [I] = S [lenの-I- 1 ] - ' 0 ' 
    }
    クリーン()   // クリアのための
    {
        memset(NUM、0はsizeof (NUM))。
    }
    ボイド F(INT N-)   // 通常の整数大きい整数の先頭に押圧され、分割たびに、後で使用される
    {
         ためINT I = LEN; I> 0 ; i-- 
            確かに、[I] = NUM [I- 1 ]。++ ;
        確かに[ 0 ] = N。
    }
    チェン(N-BigN)// 精度乗算、説明するにはあまりにも多くはありません、あなたはP1303に行くことができる質問があり、より学びます
    {
        BigN C(" 0 " )。
        INT S = 0、G = 0 以下のためにint型私は= 0 ; I <= LEN; I ++ のためのint型 J = 0 ; J <= n.lenあり、j ++ 
            {
                int型 = I + W jを。
                S = NUM [I] * n.num [J]。
                c.num [W] + = S%10 
                c.num [N + 1 ] = A + / 10 + c.num [W] / 10 
                c.num [W]%= 10 
            }
        c.len = +としてn.len。
        一方、(c.num [c.len] == 0 && c.len> = 0)c.len-- 
        FZ(C);
    }
    ボイド FZ(N-BigN)// 大きい整数に大きな整数の例外は、「=」と等価です
    {
        LEN = n.len。
        以下のためにint型私は= 0 ; I <= n.len; I ++ 
            確かに、[I] = n.num [I]。
    }
    BOOL BJ(N-BigN)   // 二つの大きな整数のサイズ、最大値を見つけるための結果を決定
    {
         IF(LEN> n.len)
             リターン 1。;
          IF(LEN < n.len)
             戻り 0 ;
         
        {
            INT I = LEN; I> = 0 ; i-- 場合(NUM [I] < n.num [i])と
                     リターン 0 それ以外の 場合(NUM [I]> n.num [i])と
                     リターン 1 リターン - 1 
        }
    }
     OUT()// 出力
    {
         のためにint型 I = LEN; I> = 0 ; i-- 
            printf(" %dの" 、NUM [I])。
    }
}。

INT N-、K、SUM [ 55 ]、B [ 55 ]、I、J; // 従来の定義、説明するために多くを行う 
BigN Mmaxをする(" 0 " )。

int型のmain()
{
    チャー S [ 101 ];   // Sを大きな整数読み取るための 
    scanfのを(" %D%D%S "、&​​N-、&K&S);
     のため(私は= 0 ; I <strlenを(S); I ++)   // の和で元の数のコピーを保つ 
        -和[I] = S [I]が' 0 ' ;
     のための(I = N- 2 ; I> =(NK) - 。1 ; i--)   // 配列b必要が配列next_permutationの上昇を使用するか、すべての構成を見つけることができないかもしれないので、ポスト1に割り当てられた番号k 
        Bを[I] = 1 ;
     行い{
        TEMP BigN(" 0 ")、全て(" 1 "); // 各セクションを分割するための保存後TEMP、各配置のためのすべての結果 
        私は= 0 ;
         ながら(I <N-)// スプリット
        {
             IF(I!= 0 IF(B [I- 1 ] == 1// Bの場合、[I-1] 1で、その後、彼らはすぐに、この1プラス乗算記号で区分の元の数を持っているでしょう 
                    all.cheng(TEMP)、temp.clean(); // 次のセクションを記憶するために、分割の数字、空の温度を乗算の数 
            temp.f(SUM [I])、I ++; / / トップの温度に圧力下で元の数
        }
        all.cheng(TEMP); // 温度によりそれほど再び、すべてのループ終了を取るしていないので、
        IF(mmax.bj(すべて)== 0// 順序前に、この結果がより大きい場合、最大結果リフレッシュ最大結果
            mmax.fz(すべて);
    } 一方(next_permutation(B、B + N- 1)); // コールnext_permutation 
    。MmaxをOUT(); // 出力
    戻り 0 ;
}

 

 

おすすめ

転載: www.cnblogs.com/hao-qing233/p/11828874.html