Test instructions: Given a string of length 2n, each character is either a number, or a?? The position should also be a character to indicate the corresponding number, but can not see clearly. Ask the question? Revert to a number, so that the product of the first n number is equal to the product of the second n number of methods of restoration how many, not equal to how many kinds?
Input:
2
2?? 3
Output:
4
96
Example explanation: The two question mark number can meet the four kinds are: 2003, 2323, 2643, 2963.
Ideas: The most difficult to do a DP, students tell me the train of thought.
1. First deal with the case that the product is 0. This is relatively simple, only with the "known 0" and "no known 0" two cases of discussion,
With the knowledge of combinatorial mathematics can be quickly calculated, skip.
2. Next consider the case that the product is not 0. (Note that there must be no known 0 in this case.) )
Considering that the 2,3,5,7 of the final product is only four of the mass factor,
Use F[i][a][b][c][d] to say: With I "?" The number of schemes that comprise the 2^a*3^b*5^c*7^d.
Enumerate the last "?" from 1 to 9 in the transfer equation The value of x, assuming x=2^ (a_x) *3^ (b_x) *5^ (c_x) *7^ (d_x), has
F[I][A][B][C][D]=SUM{F[I-1][A-A_X][B-A_X][C-C_X][D-D_X]}
The initial value f[0][0][0][0][0]=1, the others are 0.
Assume:
The first half has an ML question mark, and the product of all known numbers is al,bl,cl,dl;
The second part has Mr Question mark, and the product of all known numbers is ar,br,cr,dr;
The final answer is sum{f[ml][a-al][b-bl][c-cl][d-dl]*f[mr][a-ar][b-br][c-cr][d-dr]}+ (a scheme with a product of 0), where a,b,c,d iterates through all possible values.
Complexity of Time:
Part of product 0 can be resolved in O (n)
The Dynamic planning section can be resolved in O (n^5) due to the a<=3n,b<=2n,c<=n,d<=n
Implementation difficulties:
1. The final answer needs to be high precision, but f with a long long.
2. f has a high spatial complexity and can be used to reduce space overhead using a rolling array or a knapsack-like problem.
Write the time WA and tle several times, the test data on the official website debug 45 hours before, enough acid cool ~ ~
#include <cstdio> #include <cstring> #include <algorithm>using namespace std; #define N 18#define A n*3+ 2#define B n*2+2#define C n+2#define D n+2char str[(n<<1) +5];int Id,n,nl,nr;long long ml,mr;int res[(N<<1) +10 ],len;long long dp[2][a][b][c][d],dpt[a][b][c][d];int fac[13][4] = {//fac[1...9] for first 9 digits, fac[11] and fac[12] Indicates the product {0,0,0,0}, {0,0,0,0}, {1,0,0,0}, {0,1,0,0}, {2,0,0,0}, {0,0,1,0}, {1,1,0,0},} (0,0 , 0,1}, {3,0,0,0}, {0,2,0,0}};int base[4] = {2,3,5,7};void Jinwei () {//handles carry int i,j; for (i = 0;i<=nl+nr;i++) {j = RES[I]/10; Res[i]%= 10; Res[i+1] + = j; } len = Nl+nr; while (Len >0 &&!res[len]) len--;} void Add (Long long A,long long B) {//adds a*b to the output array because a*b may overflow a long long int i,j; if (!a | |!b) return; for (i = 0;a;i++) {long long num = a%10; Long long x = B*num; for (j = i;x;j++) {Res[j] + = x%10; x/= 10; } A/= 10; }}long Long pow (int x,int y) {//Implements the Power function, the math library directly with the math will lose precision long long sum = 1; while (y--) sum *= x; return sum;} int zero_case () {int i,j; Long Long T; if (!ml &&!mr) {//If both sides appear 0, the simplest case res[len = nl+nr] = 1; return 1; } else if (ml && MR) {//If both sides do not appear add (POW (NL)-pow (9, NL), pow (NR)-pow (9, NR));//This is a number with a product of 0 on both sides Volume return 3; } else{//Only one side appears 0 if (!ml) {t = Pow (NR)-Pow (9, NR); i = nl; }else{t = Pow (ten, NL)-POW (9, NL); i = NR; } for (j = i;t;j++) {Res[j] = t%10; T/= 10; } len = j-1; return 2; } return 0;} void Change () {//calculates the power of an existing product on the left (right) to denote int i; for (i = 0;i<4;i++) {while (ml && ml%base[i] = = 0) {fac[11][i]++; ML/= base[i]; } while (Mr && Mr%base[i] = = 0) {fac[12][i]++; Mr/= Base[i]; }}}int Check (int a,int b,int c,int d,int i) {return (a-fac[i][0]>=0) && (b-fac[i][1]>=0) && (C-FA c[i][2]>=0) && (d-fac[i][3]>=0);} int solve (int n) {int i,j,p,q=0,a,b,c,d,need; memset (DP, 0, sizeof (DP)); Dp[0][0][0][0][0] = 1; memcpy (DPT, dp[0], sizeof (dp[0])); for (i = 1;i<=n;i++) {q = i&1; Scrolling array p =!q; for (d = 0;d<=i;d++) for (c = 0;c <= i-d;c++) for (b = 0; (need= (b+1)/2+d+c) <=i;b++)//Pay attention to the judging bar The piece, counted as pruning, does not write the tle for (a = 0; ((b&1) A-1): a) +2)/3<=i-need;a++) for (j = 1;j<=9;j++) if (check (A,B,C,D,J)) Dp[q][a][b][c][d] + = dp[p][a-fac[j][0]][b-fac[j][1]][c-fac[j][2]][d-fac[j][3]]; if (i = = min (NL,NR))//Record memcpy (DPT, dp[q], sizeof (DP[Q])); memset (Dp[p], 0, sizeof (dp[p]));/Note the notation of memset} return q;} void updateres (int id) {int a,b,c,d,need; for (d = 0;d<=n;d++) for (c = 0;c <= n-d;c++) for (b = 0; (need= (b+1)/2+d+c) <=n;b++) for (a = 0; ((b&1)? ( A-1): A) (a) +2)/3<=n-need;a++) if (check (a, B, C, D, one) && check (a, B, C, D, 12)) { if (NL <= nr) Add (Dpt[a-fac[11][0]][b-fac[11][1]][c-fac[11][2]][d-fac[11][3]],dp[id] [A-fac[12][0]] [B-fac[12][1]] [C-fac[12][2]] [D-fac[12][3]]); else Add (DP[ID][A-FAC[11][0]][B-FAC[11][1]][C-FAC[11][2]][D-FAC[11][3]],DPT[A-FAC[12][0]][B-FAC [12] [1]] [C-fac[12][2]] [D-fac[12][3]]); } Jinwei ();} int main () {int i,j; NL = NR = len = 0; ML = Mr = 1; memset (res, 0, sizeof (RES)); scanf ("%d", &n); scanf ("%s", str); for (i = 0;i<n;i++) if (str[i] = = '? ') nl++; else ml *= str[i]-' 0 '; for (i= n;i<n*2;i++) if (str[i] = = '? ') nr++; Else Mr *= str[i]-' 0 '; if (Nl+nr = = 0) {//No question mark case if (ml = = MR) printf ("1\n0"); else printf ("0\n1"); return 0; } j = Zero_case (); if (j = = 1) {//Both sides appear the number 0 for (i = len;i>=0;i--) printf ("%d", res[i]); printf ("\n0"); return 0; } else if (j = = 3) {//Both sides do not appear the number 0 change (); id = Solve (max (NL,NR)); Updateres (ID); } for (i = len;i>=0;i--) printf ("%d", res[i]); Putchar (' \ n '); for (i = nl+nr-1;i>=0;i--)//There are all cases where the condition is not met res[i] = 9-res[i]; RES[NL+NR] = 0; Add (+); Jinwei (); for (i = len;i>=0;i--) printf ("%d", res[i]); return 0;}
POJ 1608 DP (banal Ticket)