数位DP总结
1、hdu2089 不要62(模板)
dp步骤:https://www.cnblogs.com/wenruo/p/4725005.html
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int dp[10][10];
int d[10];
void init()
{
dp[0][0] = 1;
for (int i = 1; i <= 7; ++i)
for (int j = 0; j <= 9; ++j)
for (int k = 0; k <= 9; ++k)
if (j != 4 && !(j == 6 && k == 2))
dp[i][j] += dp[i - 1][k];
}
int solve(int n)
{
int ans = 0;
int len = 0;
while (n) {
++len;
d[len] = n % 10;
n /= 10;
}
d[len + 1] = 0;
for (int i = len; i >= 1; --i) {
for (int j = 0; j < d[i]; ++j) {
if (d[i + 1] != 6 || j != 2)
ans += dp[i][j];
}
if (d[i] == 4 || (d[i + 1] == 6 && d[i] == 2))
break;
}
return ans;
}
int main()
{
int m, n;
init();
while (scanf("%d%d", &m, &n) == 2) {
if (n == 0 && m == 0) break;
printf("%d\n", solve(n + 1) - solve(m));
}
return 0;
}
2、HDU3555 要49(套不要62板子)
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
long long dp[20][20];
long long d[10];
void init()
{
dp[0][0] = 1;
for (int i = 1; i <= 19; ++i)
for (int j = 0; j <= 9; ++j)
for (int k = 0; k <= 9; ++k)
if (!(j == 4 && k == 9))
dp[i][j] += dp[i - 1][k];
}
long long solve(long long n)
{
long long ans = 0;
int len = 0;
while (n) {
++len;
d[len] = n % 10;
n /= 10;
}
d[len + 1] = 0;
for (int i = len; i >= 1; --i) {
for (int j = 0; j < d[i]; ++j) {
if (d[i + 1] != 4 || j != 9)
ans += dp[i][j];
}
if ((d[i + 1] == 4 && d[i] == 9))
break;
}
return ans;
}
int main()
{
long long m,n;
int t;
init();
cin>>t;
while(t--)
{
m=1;
cin>>n;
printf("%lld\n",n- solve(n + 1) + solve(m));
}
return 0;
}