スタート2019ラウンドH. Elevanagramキック

$ N = \ sum_ {i = 1から} ^ {9} a_iを$数字が設けられています。フロア{N / 2} $番号\ = $ N $最初のデジタル任意二つのグループ$ A $に分け、$ B $、$ A $ $ N_Aを有し、$ B $は$ N_B = \ CEIL {N有します/ 2} $の数字。A $図面に$および図面に$ S_A $、$ B $と呼ばれ、$ S_B $と呼びます。$場合(S_A - S_B)\ BMOD 11 \ NE 0 $、その後、調整を行います。

$ S_Bの値を - S_Aが図に$ B $、$ $ A $交換することにより、変更を検討してください。S_B \ BMOD 11 = 0 $ - ソリューションは$ S_A、いくつかのこのようなスイッチング動作の場合は合格しなければなりません。$(B)$ $交換B $の$ A $デジタルおよび$ B $に$ A $に数を表すと、交換$ Aは、その後、$ $ S_A bは - 変化量S_B $は$ - で2( - b)の$。

$私は2つの数字が存在し、J $は少なくとも$ 10 $回を受けているに気づいた場合は、その答えはYESでなければなりません。$ 10 $、$ 2Kに$ K $ $ $ 1引き継いときので(I - J)$も上$ 1~ $ $ $(10 $のセンス型で$ 11)を実行します。

各番号は以下$ 10 $回登場している場合、それはDPで解決することができます。注文$ fは、[I] [J] [K] $意味は、私はこれらの数字は、Jは、と引き抜か数字を$ 11 $のに$ K $かどうかを等しく$に$ A $からダイ$であった$、$ 1、2、\ドットを除去しました可能。同じDPにさらさ$ B $に対する。

一つだけの数のケースを考えてみましょう、少なくとも$ 10 $回登場。この数は、$ D $を設定されています。$ D $提供はD_Bに倍の$ $ $ B $登場し、$ A $ $ $ D_A回に表示されます。

これは、ドット、同等に(A_N、B_N)$は$操作(a'_1、b'_1)の配列であることができる、\ドット、(a'_k、B '\、業務$(A_1、B_1)の任意の順序で表示することができます任意の$ $ 1 \ルI、J \ルのk $、$ a'_i \ NE b'_j $のために満たす_K)。

{ - D_A、N_B - D_B \ N_A} $の一連の操作は、$ D $は$ $ $だけa_iをを表示されますのみ、特定のB_i $の存在に表示されますので、我々だけではない以上$トン= \最大\の長さを考慮する必要があります一連の操作。我々はA $を$ことができますので、$ Bは、これら二つの図少ない数DPの、$ $ $ 2、最大で撤回$ T各デジタル$ 1から$ 9 $。

int main() {
 int T;
 scan(T);
 rep (T) {
   kase();
   vl a(10);
   up (i, 1, 9) scan(a[i]);
   int n10 = 0; //出现次数大于等于10的数字的个数
   up (i, 1, 9) {
     n10 += a[i] >= 10;
   }
   if (n10 >= 2) {
     println("YES");
     continue;
   }
   ll n = accumulate(all(a), 0LL);
   ll m = n / 2;
   vl b(10);
   // 先随机分配,再通过DP判断能否进行调整。
   up (i, 1, 9) {
     if (a[i] < m) {
       swap(a[i], b[i]);
       m -= b[i];
     } else {
       b[i] = m;
       a[i] -= m;
       break;
     }
   }

   ll sa = 0, sb = 0;
   up (i, 1, 9) {
     sa += a[i] * i;
     sb += b[i] * i;
   }
   ll r = (sa - sb) % 11;
   if (r == 0) {
     println("YES");
     continue;
   }
   if (r < 0) {
     r += 11;
   }
   // r = r / 2;
   // (11 + 1) / 2 是 2 在模 11 下的拟元。
   r = r * (11 + 1) / 2 % 11;
   // dp[i][j][k] 在前i种数里选择j个数余数是否可能是k
   // 用滚动数组去掉dp数组第一维。
   auto nb = n / 2, na = n - nb;

   up (i, 1, 9) {
     if (a[i] >= 11) {
       na -= a[i];
     }
     if (b[i] >= 11) {
       nb -= b[i];
     }
   }
   auto t = max(na, nb);
   up (i, 1, 9) {
     a[i] = min(a[i], t);
     b[i] = min(b[i], t);
   }
   na = accumulate(all(a), 0LL);
   nb = accumulate(all(b), 0LL);
   vv<int> A(na + 1, vi(11));
   vv<int> B(nb + 1, vi(11));
   A[0][0] = 1;
   B[0][0] = 1;

   int ca = 0, cb = 0;

   up (i, 1, 9) {
     if (a[i] > 0) {
       down (j, ca, 0) {
         rng (k, 0, 11) {
           if (A[j][k]) {
             up (l, 1, a[i]) {
               A[j + l][(k + l * i) % 11] = true;
             }
           }
         }
       }
       ca += (int)a[i];
     }
     if (b[i] > 0) {
       down (j, cb, 0) {
         rng (k, 0, 11) {
           if (B[j][k]) {
             up (l, 1, b[i]) {
               B[j + l][(k + l * i) % 11] = true;
             }
           }
         }
       }
       cb += (int)b[i];
     }
   }

   bool flag = false;
   up (i, 1, min(na, nb)) {
     rng (j, 0, 11) {
       if (B[i][j] && A[i][(j + r) % 11]) {
         flag = true;
         break;
       }
     }
     if (flag) break;
   }
   println(flag ? "YES" : "NO");
 }
  return 0;
}

おすすめ

転載: www.cnblogs.com/Patt/p/11889930.html