HDU 6659 Acesrc and Good Numbers (数位dp)

题意:

对于f(k,n)表示的是对于(1到n)一共出现了多少次的k,注意的是例如(11它一共出现了两个1),然后给我们k和x让我们求的是一个f(k,n)第一个小于x,并且f(k,n)==n的n

 

思路:
根据数位dp来求f(k,n),很明显对于数位的统计问题一定是用数位dp来求的,其次一共有三种状态

1.当当前的数位i等于d的时候那么ans应该加上10^(pos-1),因为当前的数位若是满足条件那么后面的pos-1的数字可以随意的变化任意的值,那么就有10^pos-1种可能性

2.对于i小于a[pos]的时候,需要加上10^(pos-2)*(pos-1)个,因为对于剩余的pos-1个数字,不论前面的哪一个数位是否等于d,都可以随意的变化每一个数位的变化都可以多处10^(pos-2)个d

3.对于a[pos],也就是当前的数位的最大值,若是等于d的话那么我们后面的数字可以有限制的增加(为了不把大于x的数字也计算进去),比如12546,当我们遍历到第2数字的时候,若d==2,那么后面还有546种可能性

 

#include 
#include
#include
#include
typedef long long ll;
using namespace std;
int k;
ll n;
ll p10[20],a[20],num[20];
ll ans;
int d;
void init()
{
	int i;
	p10[0]=1;
	for(i=1;i<20;i++)
	{
		p10[i]=p10[i-1]*10;
	}
}
void dfs(int pos)
{
	if(pos==-1)return ;	
	for(int i=0;i

 

你可能感兴趣的:(数位dp,2019,HDU,多校)