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;
}

  

posted @ 2019-04-30 17:02  风雨兼程-zhi  阅读(282)  评论(0编辑  收藏  举报