题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5787
题意:要求相邻的K个位的数不能相同,在[L,R]区间有多少个这样的数.
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 int bit[20]; 7 long long dp[20][11][11][11][11]; 8 int k; 9 10 //考虑前导零:d = 10代表前一位是0, 当(d == 10 && u == 0)表示当前这位为0并且前4位都是0 11 12 bool check(int a, int b, int c, int d, int u) 13 { 14 if(k == 2) return u != d; 15 else if(k == 3) return u != d && u != c; 16 else if(k == 4) return u != d && u != c && u != b; 17 else return u != d && u != c && u != b && u != a; 18 } 19 20 long long dfs(int pos, int a, int b, int c, int d, bool flag) 21 { 22 if(pos <= 0) return d != 10; 23 long long res = dp[pos][a][b][c][d]; 24 if(flag && res != -1) return res; 25 long long ans = 0; 26 int up = flag ? 9 : bit[pos]; 27 for(int u = 0; u <= up; u++) { 28 if(d == 10 && u == 0) { 29 ans += dfs(pos - 1, a, b, c, d, flag || u != up); 30 } else if(check(a, b, c, d, u)) { 31 ans += dfs(pos - 1, b, c, d, u, flag || u != up); 32 } 33 } 34 if(flag) dp[pos][a][b][c][d] = ans; 35 return ans; 36 } 37 38 long long solve(long long x) 39 { 40 int len = 0; 41 while(x) { 42 bit[++len] = x % 10; 43 x /= 10; 44 } 45 return dfs(len, 10, 10, 10, 10, 0); 46 } 47 48 int main() 49 { 50 long long l, r; 51 while(~scanf("%I64d%I64d%d", &l, &r, &k)) { 52 memset(dp, -1, sizeof(dp)); 53 printf("%I64d ", solve(r) - solve(l - 1)); 54 } 55 return 0; 56 }
另一种:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 int bit[20]; 7 long long dp[20][11][11][11][11][2]; 8 int k; 9 10 //考虑前导零:d = 10代表前一位是0, 当(d == 10 && u == 0)表示当前这位为0并且前4位都是0 11 12 bool check(int a, int b, int c, int d, int u) 13 { 14 if(k == 2) return u != d; 15 else if(k == 3) return u != d && u != c; 16 else if(k == 4) return u != d && u != c && u != b; 17 else return u != d && u != c && u != b && u != a; 18 } 19 20 long long dfs(int pos, int a, int b, int c, int d, bool flag, bool zero) 21 { 22 if(pos <= 0) return zero; 23 long long res = dp[pos][a][b][c][d][zero]; 24 if(flag && res != -1 && zero) return res; 25 long long ans = 0; 26 int up = flag ? 9 : bit[pos]; 27 for(int u = 0; u <= up; u++) { 28 if(!zero && u == 0) { 29 ans += dfs(pos - 1, a, b, c, d, flag || u != up, 0); 30 } else if(check(a, b, c, d, u)) { 31 ans += dfs(pos - 1, b, c, d, u, flag || u != up, 1); 32 } 33 } 34 if(flag) dp[pos][a][b][c][d][zero] = ans; 35 return ans; 36 } 37 38 long long solve(long long x) 39 { 40 int len = 0; 41 while(x) { 42 bit[++len] = x % 10; 43 x /= 10; 44 } 45 return dfs(len, 10, 10, 10, 10, 0, 0); 46 } 47 48 int main() 49 { 50 long long l, r; 51 while(~scanf("%I64d%I64d%d", &l, &r, &k)) { 52 memset(dp, -1, sizeof(dp)); 53 printf("%I64d ", solve(r) - solve(l - 1)); 54 } 55 return 0; 56 }