您的位置:首页 > 其它

HDU 5787 K-wolf Number

2016-11-01 15:27 267 查看

题意

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

思路

比较裸的数位DP,但是因为刚开始没有想好思路就开始写后来调试挺长的时间。

因为K比较小,所以我们直接加4维状态分别表示前面取的四个数,每次加下一个的时候根据K判断一下就好了。有些不好处理的地方是010这种有前导零的,那么前导零我们统一用11这个数位取不到的数来表示就可以了。

代码

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: