数位dp(k的倍数的1的个数)

题目描述

给定一个整数k和一个比特数b(1≤b≤128),计算k在0和2^b−1(包括)之间的倍数的二进制表示中1位的总数,模为1000,000,000,009。

输入
输入将由两个整数k和b在一行上组成,1≤k≤1000,1≤b≤128。

输出
将结果以整数形式写在一行上。

这个题就是找k的倍数在(0,2^b-1)中,然后这些数的二进制中的1的个数

题目解析

这个题是一道数位dp,

Code:

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int mod=1000000009; 
const int maxn=1010;
int k,b;
int f[150][maxn][150]; //m为取余k的余数 ,sum为余数为1的和 
int dfs(int pos,int m,int limit,int sum){//余数和1的和 
    if(pos==0){
        if(m==0){
            return sum%mod;
        }
        else{
            return 0;
        }
    }
    if(!limit&&~f[pos][m][sum]) return f[pos][m][sum]%mod;
    int ans=0;
    for(int i=0;i<=1;i++){
        ans=(ans+dfs(pos-1,(m*2+i)%k,limit && (i == 1),(sum+(i==1))%mod))%mod; 
    } 
    if(!limit){
        f[pos][m][sum]=ans%mod;
    }
    return ans%mod;
}
int solve(){
    memset(f,-1,sizeof(f));
    return dfs(b,0,1,0);//数位 
}
int main(){
    cin>>k>>b;
    cout<<solve();
}

 

posted @ 2021-10-06 20:59  lipu123  阅读(72)  评论(0)    收藏  举报