HDU 5787 K-wolf Number

题意

求区间[l,r]中有多少个数不存在连续k位含有相同的数位。

思路

比较裸的数位DP,但是因为刚开始没有想好思路就开始写后来调试挺长的时间。
因为K比较小,所以我们直接加4维状态分别表示前面取的四个数,每次加下一个的时候根据K判断一下就好了。有些不好处理的地方是010这种有前导零的,那么前导零我们统一用11这个数位取不到的数来表示就可以了。

代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define LL long long
#define Lowbit(x) ((x)&(-x))
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1|1
#define MP(a, b) make_pair(a, b)
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
const int maxn = 1e6 + 10;
const double eps = 1e-8;
const double PI = acos(-1.0);
typedef pair<int, int> pii;

LL dig[25];
LL l, r;
int k;
LL dp[25][12][12][12][12];

LL dfs(int cur, int e, int a, int b, int c, int d, int flag)
{
    //
    if (cur <= 0)
    {
        //printf("%d %d %d %d %d %d\n", cur, e, a, b, c, d);
        return flag;
    }
    if (!e && dp[cur][a][b][c][d] != -1)
        return dp[cur][a][b][c][d];
    int end = e ? dig[cur] : 9;

    LL ans = 0;
    for (int i = 0; i <= end; i++)
    {
        if (k == 2)
        {
            if (d == i) continue;
            ans += dfs(cur - 1, i == end && e, b, c, d, i || flag ? i : 11, i || flag);
        }
        else if (k == 3)
        {
            if ((i == d || i == c)) continue;
            ans += dfs(cur - 1, i == end && e, b, c, d, i || flag ? i : 11, i || flag);
        }
        else if (k == 4)
        {
            if ((i == d || i == c || i == b)) continue;
            ans += dfs(cur - 1, i == end && e, b, c, d, i || flag ? i : 11, i || flag);
        }
        else if (k == 5)
        {
            if ((i == d || i == c || i == b || i == a)) continue;
            //printf("nei   %d %d %d %d %d %d %d\n", i, end, (i == end) && e, a, b, c, d);
            ans += dfs(cur - 1, i == end && e, b, c, d, i || flag ? i : 11, i || flag);
        }
    }
    if (!e) dp[cur][a][b][c][d] = ans;
    return ans;
}

LL Solve(LL x)
{
    if (x == 0) return 0;
    int len = 0;
    while (x)
    {
        dig[++len] = x % 10;
        x /= 10;
    }
    return dfs(len, 1, 11, 11, 11, 11, 0);
}

int main()
{
    //freopen("H:\\in.txt","r",stdin);
    //freopen("H:\\out.txt","w",stdout);
    while (scanf("%I64d%I64d%d", &l, &r, &k) != EOF)
    {
        memset(dp, -1, sizeof(dp));
        printf("%I64d\n", Solve(r) - Solve(l - 1));
    }
    return 0;
}

你可能感兴趣的:(HDOJ,数位DP)