Portal: http://oj.cnuschool.org.cn/oj/home/addSolution.htm?problemID=571
Question Description:
We call a number interesting when and only if:
1. Its numbers contain only 0, 1, 2, 3, and these four numbers appear at least once.
2. All 0 appear before all 1, and all 2 appear before all 3.
3. The maximum number of digits is not 0.
Therefore, the smallest interesting number that conforms to our definition is 2013. In addition, the 4-bit interesting number also has two: 2031 and 2301.
Please calculate the number of interesting numbers that happen to have n bits. Because the answer can be very large, only the remainder of the output answer divided by 1000000007 is required.
Input:
The input has only one row, including exactly a positive integer n (4≤n≤1000000).
Output:
The output has only one row, including the number of interesting numbers in the exact n-bit integer divided by the remainder of 1000000007.
Input Example:
4
Output Example:
3
Other Notes:
Digital dp+ forced scrolling
Exercises
First consider the solution to be persistent. First, we still have to analyze the problem.
0 can't be the first, right? That's the first one in a single-box, right? You put 1 to see the line no, certainly not ah, all 0 in front of 1, you put 1 let 0 sentiment why? Put 2 can, put 3 if you let 2 love why?
So the first place is only 2, right?
Now the status of this two-dimensional array, status[i][j] to the I position satisfies all possible numbers of J states, a total of up to 6 states:
0--0 1 (2) 3
1--(0) 1 (2) 3
2--0 1 (2) (3)
3--(0) (1) (2) 3
4--(0) 1 (2) (3)
5--(0) (1) (2) (3)
In parentheses, the number in front of the K-bit, only the number of parentheses, you can find 6 states 2 are enclosed in parentheses, no way, just said 2 must be the first
for example status[5][4] = 70 means, to the 5th place (the first is the 1th place!) So far, there are 70 of the number of 4th states (cough, of course the data is my nonsense)
and this is the only 6 states you can keep when you fill in the k+1, and the rest of the state is invalid.
For example, 0 (1) (2) 3 is invalid, it is not possible ah, if you say that you now fill in the K-bit bar, then you fill out the number of K-bit after the state is only 1 and 2, then you think, how can only appear 1 and 2? So why do you make 0 love? 0 There's no place to put it.
The following says transfer: first status[i][0] = 1;
So far as I am, the number I filled in the number so that the entire figure to meet the status 0, then there are several possible? 1 Bai, you have to be able to fill out the number of 2 outside I will go ...
status[i][1] = (status[i-1][1] * 2 + status[i-1][0])% MoD;
to the point I, fill in the number of I bits so that the whole number remains in the State 1. To meet the status 1, that is, only 0 and 2, then you think the former i-1 bit should be a state, or only 2, or 0,2, right? Just two states .
then if the former i-1 bit is state 0 (only 2), then you can only fill 0, so status[i-1][0] This is the case, if the former i-1 bit is the state 1 (there are 0, 2), then you now have two options, fill 1 or 22 cases, status[i-1 ][1] * 2 That is the case, and then add the two cases, that is, to the point I, the number of States 1 in total status[i][1] so many
and then it's all the same, because each one can go into 6 different states, so it's all going to work out .
final output STATUS[N][5], because the title requires 0,1,2,3 must appear at least once, all we want to output the number of State 5
The result of the intermediate results will definitely explode int (worst case is 3 INF plus super), so a long long to make a decision.
Persistent DP:
1#include <iostream>2#include <cstdio>3#include <algorithm>4 using namespacestd;5 Const intMoD =1000000007, MAXN =1000000+Ten;6 intN;7 Long Longstatus[maxn][6];8 voidReadint&x) {9x =0;intsig =0;Ten CharCH =GetChar (); One while(!isdigit (CH)) {if(ch = ='-') sig =-1; CH =GetChar ();} A while(IsDigit (CH)) {x =Ten* x + CH-'0'; CH =GetChar ();} - return ; - } the intsolve () { - for(inti =0; I <6; i + +) -status[0][i] =0; - for(inti =1; I <= N; i + +){ +status[i][0] =1; -status[i][1] = (Status[i-1][1] *2+ Status[i-1][0]) %MoD; +status[i][2] = (Status[i-1][2] + status[i-1][0]) %MoD; Astatus[i][3] = (Status[i-1][3] *2+ Status[i-1][1]) %MoD; atstatus[i][4] = (Status[i-1][4] *2+ Status[i-1][2] + status[i-1][1]) %MoD; -status[i][5] = (Status[i-1][5] *2+ Status[i-1][4] + status[i-1][3]) %MoD; - } - returnstatus[n][5]; - } - intMain () { in read (n); -printf"%d\n", Solve ()); to return 0; +}
Then change to a rolling DP:
1#include <iostream>2#include <cstdio>3#include <algorithm>4 using namespacestd;5 Const intMoD =1000000007;6 intN;7 Long Longstatus[2][6];8 voidReadint&x) {9x =0;intsig =0;Ten CharCH =GetChar (); One while(!isdigit (CH)) {if(ch = ='-') sig =-1; CH =GetChar ();} A while(IsDigit (CH)) {x =Ten* x + CH-'0'; CH =GetChar ();} - return ; - } the intCur =0; - intsolve () { - for(inti =0; I <6; i + +) -Status[cur][i] =0; + for(inti =1; I <= N; i + +){ -status[cur][0] =1; +status[cur][1] = (status[cur ^1][1] *2+ Status[cur ^1][0]) %MoD; Astatus[cur][2] = (status[cur ^1][2] + Status[cur ^1][0]) %MoD; atstatus[cur][3] = (status[cur ^1][3] *2+ Status[cur ^1][1]) %MoD; -status[cur][4] = (status[cur ^1][4] *2+ Status[cur ^1][2] + Status[cur ^1][1]) %MoD; -status[cur][5] = (status[cur ^1][5] *2+ Status[cur ^1][4] + Status[cur ^1][3]) %MoD; -Cur ^=1; - } - returnStatus[cur ^1][5]; in } - intMain () { to read (n); +printf"%d\n", Solve ()); - return 0; the}
Complexity O (N)
COJ 0601 Dynamic Planning (II.)