CF914C巡回セールスマンと特番

タイトル説明

正の整数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ラベルは、組み合わせの数が存在しているもの(自分の番号の組み合わせを隠していません)

 

おすすめ

転載: www.cnblogs.com/sto324/p/11401958.html