タイトル説明
正の整数xに対して、我々はそれがバイナリ「1」、我々が知っているようになることであることを操作の数を定義1 。3 1 0 = 1101 2 、1101および三つの「1」が存在するので、プライマリ13操作が3に変更されます。正の整数のために、我々は動作の後に数回行われ、ことは明らかで、それは確かに一つになるだろう。
nはバイナリで与えられる所定のnおよびkは、nはkの値の数の操作の最小数にそれを回すために、すべての決定を超えていない10 ^ 7 + 9 結果モジュロ。
1 < = N < 2 1 0 0 0、 0 <= K <= 1000 0
問題の解決策
1000バイナリー最大長Nので、1000年1の最大ので、変換時間、1000以下です。
我々は、ステップの現在の数も、X 1に必要とされるCNTを処理することができる[I] = CNT [和[i]は] + 1、和[i]はバイナリ1、合計で数i番目のための[I] =和[I ^ lowbit(I)] + 1、iは^ lowbit(i)はiが1バイナリで除去し、この番号が最初に対処しなければならない右端、それは再帰的、×1000以下であることがあります。
次に、デジタルDP、F [S] [NUM] [LIM] iがNUMに第二のプロセスに現在位置、1の数を表すことができ
最終的なCNTは[NUM] + 1 == kは一種で、numが得られた変換の数を列挙しています。
然后就WA了....
K = 0を考慮すると、出力は0になりますが、cntは、一度に操作されているので1は、解決策を見つけるのは簡単で、かつ1 = 0をkと宣告そんなに特別な、操作する必要はありません。
K = 1は、答えが2つ以上になる場合[0] CNTように0と1との間の関係は、負、その後、回答文公報kに設定されているため、これは= -1 1。
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 const int型のmod = 1000000007 ; const int型 MAXN = 1005 ; チャーS [MAXN]。 int型K、LEN、NUM [MAXN]。 int型の合計[MAXN]、CNT [MAXN]。 INT [MAXN] [MAXN] [F 2 ]。 ボイドのinit(){ 和[ 0 ] = 0 ; CNT [ 1 ] = 0 ; CNT [ 0 ] = - 2 。 以下のために(int型 = Iを1 ; I <=1000年 ; i)は和[I] =和[I ^(I&-i)] + ++ 1 。 以下のために(int型 I = 2 ; iは= < 1000 ; iは++)CNT [I] = CNT [和[I] + 1 。 } INT DFS(INT S、int型の C、ブールLIM){ もし、(S!)戻り CNT [C] + 1 == K。 もし(F [S] [C] [LIM] =! - 1)リターンF [S] [C] [LIM]。 int型のmx = LIM?NUM [S]:1 。 int型 RET = 0 ; 以下のための(int型 I = 0 ; I <= MX; iは++ ) RET =(RET + DFS(S- 1のC +(I == 1)、LIM && I == MX))%MOD。 リターン [S] [C] [LIM] = FをRET。 } int型CX(){ memsetの(F、 - 1、はsizeof (F))。 戻る DFS(LEN、0、真の); } int型のmain(){ INIT()。 scanf関数(" %sの%のD "、S&K)。 もし(!K){のprintf(" 1 ")。リターン 0 ;} でlen =のSTRLEN(S) 以下のために(int型 i = 1 ; iは= LEN <; iは++)NUMを[I] = sの[lenの-I] - ' 0 ' 。 INT ANS = CX()。 もし(Kの== 1)ans-- 。 printf(" %dの" 、ANS)。 }
インターネットは、明らかにデジタルDPラベルは、組み合わせの数が存在しているもの(自分の番号の組み合わせを隠していません)