动态规划——数位dp(入门)
数位dp一般用来解决:求在某一数据范围内的满足某项特征的数的个数这类问题。在dp数组中,一般第一项i用于表明
数字的位数,第二项j用于储存状态(有时会用多项)。
hdu2089 不要62
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089
题意就是让你求出在两个数之间的不含有‘’数字4‘’和‘’62‘’的数。
<span style="font-size:14px;">#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
int num[10]; //用于储存数,方便对数进行按位操作
int dp[10][2];//0=吉利数,1=最高位为2的吉利数
int bei10[8];
int shudp(int x)
{
int xx = x;
int ding = 0;
int bujili = 0;//不吉利数的个数
bool flag = false;
while(x > 0) // 把这个数按位分开
{
num[++ding] = x%10;
x = x/10;
}
num[ding+1] = 0;
for(int i = ding; i >= 1; i--)
{
bujili += num[i]*(bei10[i-1]-dp[i-1][0]);
if(flag)
{
bujili += dp[i-1][0]*num[i];
}
else
{
if(num[i] > 4)
bujili += dp[i-1][0];
if(num[i+1] == 6 && num[i] > 2)
bujili += dp[i][1];
if(num[i] > 6)
bujili += dp[i-1][1];
if(num[i] == 4 || (num[i+1] == 6 && num[i] == 2) )
flag = true;
}
}
if(flag) // 如果这个数本身也是不吉利数,要单独处理。
bujili++;
return
xx-bujili;
}
void init()
{
memset(dp,0,sizeof(dp));
dp[0][0] = 1;
bei10[0] = 1;
for(int i = 1; i <= 9; i++)
{
dp[i][0] = dp[i-1][0]*9-dp[i-1][1];
dp[i][1] = dp[i-1][0];
bei10[i] = bei10[i-1]*10;
}
}
int main()
{
int left,right;
init();
while(~scanf("%d%d",&left,&right))
{
if(left == 0 && right == 0)
return 0;
printf("%d\n",shudp(right)-shudp(left-1));// 对于某一区间内的求取,可以通过做差来获得。
}
return 0;
}</span>