HDU 5787:K-wolf Number(数位DP)

时间:2022-05-26 19:30:01

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5787

题意:要求相邻的K个位的数不能相同,在[L,R]区间有多少个这样的数.

 #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; int bit[];
long long dp[][][][][];
int k; //考虑前导零:d = 10代表前一位是0, 当(d == 10 && u == 0)表示当前这位为0并且前4位都是0 bool check(int a, int b, int c, int d, int u)
{
if(k == ) return u != d;
else if(k == ) return u != d && u != c;
else if(k == ) return u != d && u != c && u != b;
else return u != d && u != c && u != b && u != a;
} long long dfs(int pos, int a, int b, int c, int d, bool flag)
{
if(pos <= ) return d != ;
long long res = dp[pos][a][b][c][d];
if(flag && res != -) return res;
long long ans = ;
int up = flag ? : bit[pos];
for(int u = ; u <= up; u++) {
if(d == && u == ) {
ans += dfs(pos - , a, b, c, d, flag || u != up);
} else if(check(a, b, c, d, u)) {
ans += dfs(pos - , b, c, d, u, flag || u != up);
}
}
if(flag) dp[pos][a][b][c][d] = ans;
return ans;
} long long solve(long long x)
{
int len = ;
while(x) {
bit[++len] = x % ;
x /= ;
}
return dfs(len, , , , , );
} int main()
{
long long l, r;
while(~scanf("%I64d%I64d%d", &l, &r, &k)) {
memset(dp, -, sizeof(dp));
printf("%I64d\n", solve(r) - solve(l - ));
}
return ;
}

另一种:

 #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; int bit[];
long long dp[][][][][][];
int k; //考虑前导零:d = 10代表前一位是0, 当(d == 10 && u == 0)表示当前这位为0并且前4位都是0 bool check(int a, int b, int c, int d, int u)
{
if(k == ) return u != d;
else if(k == ) return u != d && u != c;
else if(k == ) return u != d && u != c && u != b;
else return u != d && u != c && u != b && u != a;
} long long dfs(int pos, int a, int b, int c, int d, bool flag, bool zero)
{
if(pos <= ) return zero;
long long res = dp[pos][a][b][c][d][zero];
if(flag && res != - && zero) return res;
long long ans = ;
int up = flag ? : bit[pos];
for(int u = ; u <= up; u++) {
if(!zero && u == ) {
ans += dfs(pos - , a, b, c, d, flag || u != up, );
} else if(check(a, b, c, d, u)) {
ans += dfs(pos - , b, c, d, u, flag || u != up, );
}
}
if(flag) dp[pos][a][b][c][d][zero] = ans;
return ans;
} long long solve(long long x)
{
int len = ;
while(x) {
bit[++len] = x % ;
x /= ;
}
return dfs(len, , , , , , );
} int main()
{
long long l, r;
while(~scanf("%I64d%I64d%d", &l, &r, &k)) {
memset(dp, -, sizeof(dp));
printf("%I64d\n", solve(r) - solve(l - ));
}
return ;
}