某人刚学习了数位DP,他在某天忽然思考如下问题:
给定n,问有多少数对<x, y>满足:
x, y∈[1, n], x < y
x, y中出现的[0, 9]的数码种类相同
标签:names size 数位dp space 问题 std 分享图片 ring 学习
某人刚学习了数位DP,他在某天忽然思考如下问题:
给定n,问有多少数对<x, y>满足:
x, y∈[1, n], x < y
x, y中出现的[0, 9]的数码种类相同
一个整数n (n <= 107)
输出一个数即答案
30
3
<1, 11> <2, 22> <12, 21>
这题是思路是x,y在1~n内,而且x和y中出现的数码相同,因此,我们可以暴力存从1到n的所有数码状态的个数。 然后求个组合就行了。
比如:12 121 121212 1212121 212121 这几个数的数码都是12,那么数码为12的个数为5,这五个数任取两个都可以组成一种x,y。
具体看代码:
1 #include<iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <algorithm> 6 #include <string> 7 typedef long long ll; 8 using namespace std; 9 const int maxn = 1e6; 10 const int inf = 0x3f3f3f3f; 11 int nu[maxn]; 12 int dis[maxn]; 13 int vis[11]; 14 using namespace std; 15 int main() 16 { 17 int n; 18 scanf("%d", &n); 19 for(int i = 1; i <= n; ++i) { 20 memset(vis, 0 , sizeof(vis)); 21 int x = i; 22 while(x) { 23 vis[x % 10] = 1; 24 x /= 10; 25 } 26 int num = 0; 27 for(int j = 0; j <= 9; ++j) { 28 if(vis[j]) { 29 num += 1 << j; 30 } 31 } 32 nu[num]++; 33 } 34 ll ans = 0; 35 for(int i = 0; i < (1 << 10); ++i) { 36 if(nu[i]) 37 ans += nu[i] * (nu[i] - 1) / 2; 38 } 39 printf("%lld\n", ans); 40 return 0; 41 }
标签:names size 数位dp space 问题 std 分享图片 ring 学习
原文地址:https://www.cnblogs.com/zmin/p/8976198.html