D Count The Bits
题意:
输入
k
,
b
(
1
≤
k
≤
1000
,
1
≤
b
≤
128
)
;
k,b(1\leq k\leq 1000,1\leq b\leq128);
k,b(1≤k≤1000,1≤b≤128);
问在
[
0
,
2
b
)
[0,2^b)
[0,2b)以内
k
k
k的倍数位为
1
1
1的个数的和。
题解1(dp):
设
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示
[
0
,
2
i
)
[0,2^i)
[0,2i)以内模
k
k
k为
j
j
j的数的个数;
设
f
[
i
]
[
j
]
f[i][j]
f[i][j]表示
[
0
,
2
i
)
[0,2^i)
[0,2i)以内模
k
k
k为
j
j
j的数的位为1个数和。
转移:
d
p
[
i
]
[
j
]
=
d
p
[
i
−
1
]
[
j
]
+
d
p
[
i
−
1
]
[
j
−
(
1
<
<
i
)
]
dp[i][j]=dp[i-1][j]+dp[i-1][j-(1<<i)]
dp[i][j]=dp[i−1][j]+dp[i−1][j−(1<<i)]即考虑第
i
i
i位为
0
0
0和为
1
1
1的情况;
f
[
i
]
[
j
]
=
f
[
i
−
1
]
[
j
]
+
f
[
i
−
1
]
[
j
−
(
1
<
<
i
)
]
+
d
p
[
i
−
1
]
[
j
−
(
1
<
<
i
)
]
f[i][j]=f[i-1][j]+f[i-1][j-(1<<i)]+dp[i-1][j-(1<<i)]
f[i][j]=f[i−1][j]+f[i−1][j−(1<<i)]+dp[i−1][j−(1<<i)]同上考虑。
代码没写。
题解2(数位dp):
设 d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k]为到第 i i i位,模 k k k为 j j j,1的个数为 k k k,的方案数,然后按数位 d p dp dp套路搞搞就好了。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1009;
int k,b;
const int mod=1e9+9;
int dp[139][N][139];
int dfs(int x,int y,int cnt,bool lim){
if(x<0)return y==0?cnt:0;
if(!lim&&dp[x][y][cnt]!=-1)return dp[x][y][cnt];
int sum=0;
for(int i=0;i<=1;i++){
sum=(sum+dfs(x-1,(y*2+i)%k,cnt+i,lim&i))%mod;
}
return dp[x][y][cnt]=sum;
}
int solve(){
memset(dp,-1,sizeof(dp));
return dfs(b-1,0,0,1);
}
signed main(){
// freopen("tt.in","r",stdin),freopen("tt.out","w",stdout);
cin>>k>>b;
cout<<solve()<<endl;
return 0;
}