數字dp好虛啊。。最近練練。
首先我們要對題意進行合理的轉化: xx
or3x
=2x 就等價於xx
or2x
=3x ,且我們知道x+
2x=3
x ,即
x 與
x<<
1在相加時不能有進製,所以有xa
nd(x
<<1)
=0,那麼就轉化為區間內滿足這個條件的數量。 用f
i 表示二進位制表示下有
i 位,且最高位為
0的個數,用gi
表示二進位制表示下有
i 位,且最高位為
1的個數。
那麼轉移顯然:fi
=fi−
1+gi
−1,g
i=fi
−1先看第二問,第二問其實就是要求fn
,因為fn
表示的是[0
,2n)
的答案個數,而
0 不是正整數,2n
是合法答案,所以總共還是有fn
個,打表可以發現fn
是fib
onac
ci數列的第n+
2 項,可以直接矩陣乘法求。
再看第一問,這是乙個數字dp。 加入n
=22,將n+
1 表示成二進位制
10111
,並將答案劃分成幾段: [0
,01111
] ,答案為f4
。 [10000
,10011
] ,答案為f2
。 [10100
,10101
] ,答案為f1
。 [10110
,10111
] ,由於有相鄰的
1 存在,後面的答案都一定不合法,計算結束。
最後要減
1,因為
0 是不合法的。
數字dp一直很弱,一是邊界問題,二是計數問題,還要多加練習啊。
#include
#include
#include
#define ll long long
#define mod 1000000007
using
namespace
std;
ll f[70],g[70];
struct matrix
friend matrix operator*(matrix a,matrix b)
friend matrix operator^(matrix a,ll b)
};inline ll read()
while (c>='0'&&c<='9')
return a*f;
}inline ll query_1(ll x)
else flag=0;
return ans-1;
}inline ll query_2(ll x)
int main()
return
0;}
BZOJ 1833 count 數字計數 數字DP
description 給定兩個正整數a和b,求在 a,b 中的所有整數中,每個數碼 digit 各出現了多少次。input 輸入檔案中僅包含一行兩個整數a b,含義如上所述。output 輸出檔案中包含一行10個整數,分別表示0 9在 a,b 中出現了多少次。解題報告 這道題很容易看出是乙個數字d...
ARC075F Mirrored 搜尋 數字dp
給定正整數dd,求有多少個正整數nn,滿足rev n n drev n n d,其中rev n rev n 表示將nn的十進位制表示翻轉來讀得到的數 乙個正整數dd 滿足上述條件的正整數的個數 case 1 63case 2 75case 3 864197532case 1 2case 2 0cas...
Codeforces 1073E 狀壓 數字dp
題意 輸入l r k,輸出區間 l,r 內數字種數不超過k的數字之和,比如l 10,r 50,k 1,答案就是11 22 33 44 110 1 l 1e18,1 e 1e18,1 k 9 思路比較明顯的數字dp,因為要考慮當前所用的數字種類所以要把用過的數字狀壓一下,用dp i s 表示從低到高遞...