数位DP总结

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

你可能感兴趣的:(dp)