BNU 12639 cards
DP expectation
Distinguish global optimal selection from current optimal selection.
This is the best choice currently.
Status:
Double DP [16] [16] [16] [16] [5] [5];
Bool vis [16] [16] [16] [16] [5] [5];
Status parameters:
Vector <int> up, vector <int> TMP.
So,Memory search + backtracking
// # Pragma warning (Disable: 4786) // # pragma comment (linker, "/Stack: 16777216 ") // head # include <cstdio> # include <ctime> # include <cstdlib> # include <cstring> # include <queue> # include <string> # include <set> # include <stack> # include <map> # include <cmath> # include <vector> # include <iostream> # include <algorithm> using namespace STD; // loop # define Fe (I, a, B) for (INT I = (a); I <= (B); ++ I) # define FD (I, b, A) fo R (INT I = (B); I >= (a); -- I) # define rep (I, n) for (INT I = 0; I <(N ); ++ I) # define CLR (A, value) memset (A, value, sizeof (A) # define CPY (a, B) memcpy (A, B, sizeof (A) # define FC (it, c) for (_ typeof (c ). begin () it = (c ). begin (); it! = (C ). end (); It ++) // input # define RI (n) scanf ("% d", & N) # define RII (n, m) scanf ("% d", & N, & M) # define riii (n, m, k) scanf ("% d", & N, & M, & K) # define RS (s) scanf ("% s", S) // output # define wi (n) printf ("% d \ n ", n) # define WS (s) printf ("% s \ n", S) typedef long ll; const int INF = 1000000007; const double EPS = 1e-10; const int maxn = 1010; vector <int> goal; double DP [16] [16] [16] [16] [5] [5]; bool vis [16] [16] [16] [16] [5] [5]; inline bool check (vector <int> & TMP) {for (INT I = 0; I <4; I ++) if (goal [I]> TMP [I]) return false; return true;} double DFS (vector <int> & TMP, vector <int> & UP) {If (check (TMP) return 0.0; if (vis [TMP [0] [TMP [1] [TMP [2] [TMP [3] [TMP [4] [TMP [5]) return DP [TMP [0] [TMP [1] [TMP [2] [TMP [3] [TMP [4] [TMP [5]; vis [TMP [0] [TMP [1] [TMP [2] [TMP [3] [TMP [4] [TMP [5] = true; double ret = 0; int tot = 0; rep (I, 4) tot + = TMP [I]; Tot = 54-tot; rep (I, 4) {If (up [I]> TMP [I]) {TMP [I] ++; RET + = (up [I]-TMP [I] + 1.0) /tot * DFS (TMP, up); TMP [I] -- ;}} if (up [4]) {double retmin = 100; rep (I, 4) {TMP [I] ++; up [I] ++; up [4] --; TMP [4] = I + 1; retmin = min (retmin, 1.0/tot * DFS (TMP, UP); TMP [I] --; up [I] --; up [4] ++; TMP [4] = 0 ;} RET + = retmin;} If (up [5]) {double retmin = 100; rep (I, 4) {TMP [I] ++; up [I] ++; up [5] --; TMP [5] = I + 1; retmin = min (retmin, 1.0/tot * DFS (TMP, UP); TMP [I] --; up [I] --; up [5] ++; TMP [5] = 0;} RET + = retmin ;} DP [TMP [0] [TMP [1] [TMP [2] [TMP [3] [TMP [4] [TMP [5] = ++ RET; return ret;} int main () {int t; int ncase = 1; RI (t); While (t --) {int xx = 0, TOT = 0; goal. clear (); rep (I, 4) {int X; RI (x); Goal. push_back (x); If (x> 13) xx + = x-13; Tot + = x;} double ans; If (TOT> 54 | XX> 2) {ans =-1.000;} else {memset (VIS, 0, sizeof (VIS); vector <int> TMP, up; rep (I, 6) TMP. push_back (0); rep (I, 4) up. push_back (13); rep (I, 2) up. push_back (1); ans = DFS (TMP, up); If (ANS <0) ans = 0.000;} printf ("case % d: %. 3lf \ n ", ncase ++, ANS);} return 0 ;}
A little different way of writing
// # Pragma warning (Disable: 4786) // # pragma comment (linker, "/Stack: 16777216 ") // head # include <cstdio> # include <ctime> # include <cstdlib> # include <cstring> # include <queue> # include <string> # include <set> # include <stack> # include <map> # include <cmath> # include <vector> # include <iostream> # include <algorithm> using namespace STD; // loop # define Fe (I, a, B) for (INT I = (a); I <= (B); ++ I) # define FD (I, b, A) fo R (INT I = (B); I >= (a); -- I) # define rep (I, n) for (INT I = 0; I <(N ); ++ I) # define CLR (A, value) memset (A, value, sizeof (A) # define CPY (a, B) memcpy (A, B, sizeof (A) # define FC (it, c) for (_ typeof (c ). begin () it = (c ). begin (); it! = (C ). end (); It ++) // input # define RI (n) scanf ("% d", & N) # define RII (n, m) scanf ("% d", & N, & M) # define riii (n, m, k) scanf ("% d", & N, & M, & K) # define RS (s) scanf ("% s", S) // output # define wi (n) printf ("% d \ n ", n) # define WS (s) printf ("% s \ n", S) typedef long ll; const int INF = 1000000007; const double EPS = 1e-10; const int maxn = 1010; vector <int> goal; double DP [14] [14] [14] [14] [5] [5]; bool vis [14] [14] [14] [14] [5] [5]; inline bool check (vector <int> & TMP) {int xx = TMP [4], YY = TMP [5]; if (XX) TMP [XX-1] ++; If (yy) TMP [yy-1] ++; bool ret = true; For (INT I = 0; I <4; I ++) if (goal [I]> TMP [I]) ret = false; If (XX) TMP [XX-1] --; If (yy) TMP [yy-1] --; return ret;} double DFS (vector <int> & TMP) {If (check (TMP) return 0.0; if (vis [TMP [0] [TMP [1] [TMP [2] [TMP [3] [TMP [4] [TMP [5]) return DP [TMP [0] [TM P [1] [TMP [2] [TMP [3] [TMP [4] [TMP [5]; vis [TMP [0] [TMP [1] [TMP [2] [TMP [3] [TMP [4] [TMP [5] = true; double ret = 0; int tot = 0; rep (I, 4) tot + = TMP [I]; int xx = TMP [4], YY = TMP [5]; if (XX) tot ++; If (yy) tot ++; Tot = 54-tot; rep (I, 4) {If (13> TMP [I]) {TMP [I] ++; RET + = (13-TMP [I] + 1.0)/tot * DFS (TMP); TMP [I] -- ;}} if (! XX) {double retmin = 100; rep (I, 4) {TMP [4] = I + 1; retmin = min (retmin, 1.0/tot * DFS (TMP )); TMP [4] = 0;} RET + = retmin;} If (! YY) {double retmin = 100; rep (I, 4) {TMP [5] = I + 1; retmin = min (retmin, 1.0/tot * DFS (TMP )); TMP [5] = 0;} RET + = retmin ;} DP [TMP [0] [TMP [1] [TMP [2] [TMP [3] [TMP [4] [TMP [5] = ++ RET; return ret;} int main () {int t; int ncase = 1; RI (t); While (t --) {int xx = 0, TOT = 0; goal. clear (); rep (I, 4) {int X; RI (x); Goal. push_back (x); If (x> 13) xx + = x-13; Tot + = x;} double ans; If (TOT> 54 | XX> 2) {ans =-1.000;} else {memset (VIS, 0, sizeof (VIS); vector <int> TMP; rep (I, 6) TMP. push_back (0); ans = DFS (TMP); If (ANS <0) ans = 0.000;} printf ("case % d: %. 3lf \ n ", ncase ++, ANS);} return 0 ;}