Topic description
Someone just learned digital DP, and he suddenly thought about the following questions one day:
Given n, ask how many pairs <x, y> satisfy:
x, y∈[1, n], x < y
The numbers of [0, 9] appearing in x, y are the same
enter
an integer n (n <= 10 7 )
output
output a number as the answer
sample input
30
Sample output
3
hint
<1, 11> <2, 22> <12, 21>
Ideas:
Violent enumeration from 1 to n, the result is added with the number of the same number of digits that have appeared before this number, and then the number of the same number of digits is added by one;
Use vis[] to store the number of digits of each type.
// vis[i], convert i into a binary number, from left to right
// those bits are 1, then the value of vis[i] is the number of times these numbers have appeared
// for example i = 3 = 0000000110
// vis[3] is the number of numbers where only 1 and 2 appear
The worst time complexity I think is around 5 * 10^7, but it can be AC.
#include <iostream> #include <cstring> using namespace std; int vis[1<<11]; // vis[i], convert i to binary number, from left to right // Those bits are 1, then the value of vis[i] is the number of times these numbers have appeared // eg i = 3 = 0000000110 // vis[3] is only the number of numbers 1 and 2 intmain() { int n, temp, now; cin >> n; memset(vis, 0, sizeof(vis)); long long ans = 0; for(int i=1; i<=n; i++) { temp = i; now = 0; while(temp > 0) { now |= 1<<(temp%10); temp /= 10; } if(vis[now]) { // If there is less than i and the same digital type only appears // update result years += vis[now]; } // update vis[] vis[now] ++; } cout << ans << endl;. return 0; }