题目:hdu 2089
题意:求不包含4或62的个数
tag:数位dp
对于组成各种数字的状态,我们分为以下几种:
S0:不存在4 且 不存在连续的 62
S1:不存在4 且 不存在连续的 62 且 第一位不2
S2:存在 4 或者 62
对于每个状态,得到的下一个状态,假定为将(0~9)的数字插在前面,那么:S1状态可由S0状态前面直接加2得到;S2状态由S1状态前面加6或者由S0状态前面加4得到,或者已经是S2状态了,随便插个数字;S0状态由S0状态前面插上一个4以外的数字,但是得除去6插在首位为2的那种S1的状态。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
int dp[8][3];
void init()
{
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for (int i = 1; i < 8; i++)
{
// i位,不存在 4 和 62
dp[i][0] = 9 * dp[i - 1][0] - dp[i - 1][1]; //添4以外的9个数,除去6和首位为2的组合
// 不存在4 和 62 ,但首位为2
dp[i][1] = dp[i - 1][0]; //直接加2
// 存在 4 或 62 的
dp[i][2] = dp[i - 1][1] + dp[i - 1][0] + 10 * dp[i - 1][2];//直接添6;直接添4;或者已经是不幸运的,随便添一个
}
}
int solve(int n)
{
int tmp = n;
int bit[8];
for (int i = 1; i < 8; i++)
{
bit[i] = tmp % 10;
tmp /= 10;
}
int ans = 0;
bool tag = false;
for (int i = 6; i >= 1; i--)
{
ans += bit[i] * dp[i - 1][2];
if (tag)
ans += bit[i] * dp[i - 1][0];
else
{
if (bit[i + 1] == 6 && bit[i] > 2)
ans += dp[i][1];
if (bit[i] > 4)
ans += dp[i - 1][0];
if (bit[i] > 6)
ans += dp[i - 1][1];
}
if ((bit[i] == 4) || (bit[i] == 2 && bit[i + 1] == 6))
tag = true;
}
return n - ans;
}
int main()
{
int l, r;
init();
while (scanf("%d%d", &l, &r) != EOF)
{
if (l == 0 && r == 0)
break;
printf("%d\n", solve(r + 1) - solve(l));
}
return 0;
}
题目:hdu 3555
题意:求包括49的数字
tag:数位dp
思路:同上
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long LL;
LL dp[20][3];
void init()
{
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for (int i = 1; i < 20; i++)
{
dp[i][0] = 10 * dp[i - 1][0] - dp[i - 1][1];
dp[i][1] = dp[i - 1][0];
dp[i][2] = 10 * dp[i - 1][2] + dp[i - 1][1];
}
}
LL solve(LL n)
{
LL tmp = n;
int bit[20];
for (int i = 1; i < 20; i++)
{
bit[i] = tmp % 10;
tmp /= 10;
}
bool tag = false;
LL ans = 0;
for (int i = 19; i >= 1; i--)
{
ans += bit[i] * dp[i - 1][2];
if (tag)
ans += bit[i] * dp[i - 1][0];
else
{
if (bit[i] > 4)
ans += dp[i - 1][1];
}
if (bit[i] == 9 && bit[i + 1] == 4)
tag = true;
}
return ans;
}
int main()
{
init();
LL n;
int t;
scanf("%d", &t);
while (t--)
{
scanf("%I64d", &n);
printf("%I64d\n", solve(n + 1));
}
return 0;
}