Gym - 101982D (数位dp)
Given an integer k and a number of bits b (1 ≤ b ≤ 128), calculate the total number of 1 bits in the binary representations of multiples of k between 0 and 2^b − 1 (inclusive), modulo 1,000,000,009. Input The input will consist of two integers k and b on a single line, with 1 ≤ k ≤ 1000 and 1 ≤ b ≤ 128. Output Write your result as an integer on a single line.
Sample Input and Output
1 4
32
10 5
8
100 7
3
3 28
252698795
11 128
856188165
1 26
872415232
876 128
530649653
题目链接:https://codeforces.com/gym/101982/attachments
题意:给出两个数k,m。问:在0-2^m-1中,为k的倍数的数字的二进制中,总共有多少个1;如k=2 ,m=3时,在0-2^3-1中为二的倍数有10,110,100,所以一共有4个1;即此时答案为4。
解题思路:很明显是数位dp的题目,我们先定义某种状态dp【pos】【k】,状态意为:当前数位为pos,mod k(k为输入的那个)的余数,然后用结构体来记录当前状态有多少个符合的数字count(即被k整除),ans记录这些数字二进制总共有多少个1.
#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll mod=1e9+9; int p,k; struct st{ int count;//记录符合数字的个数 ll ans;//记录所需的答案 st():count(-1),ans(0){} st(int count,ll ans):count(count),ans(ans){} }dp[150][1005]; st dfs(int pos,int tem,bool limit){ if(pos==-1){ //cout<<count<<" "<<tem<<endl; if(tem==0){ return st(1,0); } return st(0,0); } if(dp[pos][tem].count!=-1&&!limit){ return dp[pos][tem]; } st ans; ans.count=0;//这里不要忘了赋值为零,因为初始值为-1 int up=1; for(int i=0;i<=up;i++){ st tem1=dfs(pos-1,(tem*2+i)%k,i==up&&limit); ans.count=(ans.count+tem1.count)%mod;//状态转移 ans.ans=(ans.ans+i*tem1.count+tem1.ans)%mod;///状态转移 } if(!limit)dp[pos][tem]=ans; return ans; } int main(){ scanf("%d%d",&k,&p); cout<<dfs(p-1,0,true).ans<<endl; return 0; }