HDU 4352 XHXJ's LIS, hduxhxj
XHXJ's LIS
Obtain the number in the given range [L, R] (0 <L <= R <263-1 and 1 <= K <= 10 ).LIS (non-continuous strictly incrementing subsequence)Is the number of K?
For example, the LIS of 123,321 in the range [124] is 3;
<1> summarizeOptimization Method:
- To sum up the similarities between high positionsStatusConversion is the key;
Example: 1. In the beautiful number of codeforces, the number of records that can be divisible by each non-zero number must be satisfied. At this time, the lcm is constructed. When the high-level mod (the lcm of all elements is directly optimized to 2520), there will be many overlapping sub-problems, which is the State transfer; of course, the various lcm only need to be stored;
2. first, you need to know how to solve LIS for a given sequence, such as 1 2 4 6. When 3 is added, the minimum value of LIS with a length of 3 is 3, instead of 4. (using arrays to store [length] = minval), but this question is not such a LIS. This requires a Fuzzy View to regard different heights as the same, only overlapping sub-structures can exist.
At the beginning of dfs, state is 0. If we add 1 after 98, then the original LIS length is 1, but here the length is 3. Why? Because the state stores only the state, that is to say, when the dfs to the pos-1 bit, only know the value of the previous, do not need to know the order of ~~ This simplifies the Sorting Problem to the combination problem, which is the essence of optimization. This is why the number of 1 in the state is the value of LIS (deliberately arranged in ascending order)
But there are still problems:
- Can I add a number directly without deleting the previous status? No, because when you only add the number of the position, you will find that when the number of 1 in the final judgment is k, only the value of k appears. For example, you can only set a value like 221,133,144, but not a value like 198. Therefore, you must delete it.
- Number of deletions? Delete only one question. If you want to put the currently inserted value to the end, you need to delete all the larger values in the end, but this is a combination problem, you only need to optimize the value of this number. That is, if the first number is 1 2 4 5 and the inserted number is 3 and the LIS length is 3, and the previous value is 4, change 4 to 3. at first, I thought about deleting the maximum value. Is it better to insert the current value? However, a large number of values are missing. (After you change the value of sample input, the result is 125. If the number is less than 191,190,291,290,292, the result is );
- Can the front-end 0 be used? 1. when the state is still 0, 0 cannot be added to the state, but when the state has been added to the element, you can; for Case 1, this is the front of the value 0, if this parameter is added, it will repeat the number with the same value. For Case 2, we can use it as the same length value for the optimization of the LIS above.
At this point, we can determine that the dfs parameter is four pos, state, edge (originally available), and whether there is a zero parameter with a front 0.
(The built-in function _ builtin_popcount () is used to calculate the number of digits 1)
# Include <bits/stdc ++. h> using namespace std; # define rep (I, n) for (int (I) = 0; I <(n); I ++) # define MS1 () memset (a,-1, sizeof (a) typedef long ll; ll dp [20] [1 <10] [11]; int bit [20], K; int newstate (int state, int v) {for (int I = v; I <10; I ++) if (state & (1 <I )) return (state ^ (1 <I) | (1 <v); return state | (1 <v);} ll dfs (int pos, int state, bool edge, bool zero) {if (pos =-1) return _ builtin_popcount (st Ate) = K; if (! Edge & dp [pos] [state] [K]! =-1) return dp [pos] [state] [K]; int end = edge? Bit [pos]: 9; ll ans = 0; for (int I = 0; I <= end; I ++) {ans + = dfs (pos-1, (zero & I = 0 )? 0: newstate (state, I), edge & I = end, zero & I = 0);} if (! Edge) dp [pos] [state] [K] = ans; return ans;} ll calc (ll x) {int tot = 0; while (x) {bit [tot ++] = x % 10; x/= 10;} return dfs (tot-,);} int main () {int T, kase = 1; MS1 (dp); cin> T; while (T --) {ll L, R; scanf ("% I64d % I64d % d", & L, & R, & K); printf ("Case # % d: % I64d \ n", kase ++, calc (R)-calc (L-1 ));}}View Code