Pressure DP
Let's take a look at Example 9-17.
/* // Uva1412 fund management // The program times out, it is only used to demonstrate how to write complex state dynamic planning using encoding/decoding methods. // rujia Liu # include <cstdio> # include <cstring> # include <map> using namespace STD; const double INF = 1e30; const int maxn = 8; const int maxm = 100 + 5; Map <int, double> d [maxm]; Map <int, int> OPT [maxm], prevv [maxm]; int M, N, S [maxn], K [maxn], KK; double C, price [maxn] [maxm]; char name [maxn] [10]; int encode (int * portfolio) {int h = 0; For (int I = 0; I <n; I ++) H = H * 9 + portfolio [I]; return h;} int decode (INT H, int * portfolio) {int totlot = 0; For (INT I = n-1; I> = 0; I --) {portfolio [I] = H % 9; totlot + = portfolio [I]; h/= 9;} return totlot;} void Update (INT oldh, int day, int H, Double V, int o) {If (d [Day]. count (H) = 0 | V> d [Day] [H]) {d [Day] [H] = V; OPT [Day] [H] = O; prevv [Day] [H] = oldh;} double dp () {int portfolio [maxn]; D [0] [0] = C; For (INT day = 0; day <m; day ++) for (Map <int, double> :: iterator it = d [Day]. begin (); it! = D [Day]. end (); It ++) {int H = it-> first; Double V = it-> second; int totlot = decode (H, portfolio); Update (H, day + 1, h, V, 0); // hold for (INT I = 0; I <n; I ++) {If (portfolio [I] <K [I] & totlot <KK & V> = Price [I] [Day]-1e-3) {portfolio [I] ++; update (H, day + 1, encode (portfolio), V-price [I] [Day], I + 1); // buy portfolio [I] --;} if (portfolio [I]> 0) {portfolio [I] --; Update (H, day + 1, encode (portfolio), V + price [I] [Day], -i-1); // returns portfolio [I] ++;} return d [m] [0];} void print_ans (INT day, int H) {If (Day = 0) return; print_ans (day-1, prevv [Day] [H]); If (OPT [Day] [H] = 0) printf ("hold \ n"); else if (OPT [Day] [H]> 0) printf ("buy % s \ n ", name [OPT [Day] [H]-1]); else printf ("bytes % s \ n ", name [-OPT [Day] [H]-1]);} int main () {int Kase = 0; while (scanf ("% lf % d", & C, & M, & N, & KK) = 4) {If (Kase ++> 0) printf ("\ n"); For (INT I = 0; I <n; I ++) {scanf ("% S % d", name [I], & S [I], & K [I]); For (Int J = 0; j <m; j ++) {scanf ("% lf ", & Price [I] [J]); price [I] [J] * = s [I] ;}} for (INT I = 0; I <= m; I ++) {d [I]. clear (); OPT [I]. clear (); prevv [I]. clear () ;}double ans = dp (); printf ("%. 2lf \ n ", ANS); print_ans (M, 0);} return 0 ;} */# include <cstdio> # include <cstring> # include <vector> # include <map> using namespace STD; const double INF = 1e30; const int maxn = 8; const int maxm = 100 + 5; const int maxstate = 15000; int M, N, S [maxn], K [maxn], KK; double C, price [maxn] [maxm]; char name [maxn] [10]; double d [maxm] [maxstate]; int OPT [maxm] [maxstate], prevv [maxm] [maxstate]; int buy_next [maxstate] [maxn], sell_next [maxstate] [maxn]; vector <int> states; map <vector <int>, int> ID; void DFS (INT stock, vector <int> & lots, int totlot) {If (stock = N) {ID [lots] = states. size (); States. push_back (lots);} else for (INT I = 0; I <= K [stock] & totlot + I <= KK; I ++) {lots [stock] = I; DFS (stock + 1, lots, totlot + I) ;}} void Init () {vector <int> lots (n); States. clear (); Id. clear (); DFS (0, lots, 0); For (int s = 0; S <states. size (); s ++) {int totlot = 0; For (INT I = 0; I <n; I ++) totlot ++ = States [s] [I]; for (INT I = 0; I <n; I ++) {buy_next [s] [I] = sell_next [s] [I] =-1; if (States [s] [I] <K [I] & totlot <KK) {vector <int> newstate = States [s]; newstate [I] ++; buy_next [s] [I] = ID [newstate];} If (States [s] [I]> 0) {vector <int> newstate = States [s]; newstate [I] --; sell_next [s] [I] = ID [newstate] ;}}} void Update (INT day, int S, int S2, Double V, int o) {If (V> d [day + 1] [s2]) {d [day + 1] [s2] = V; OPT [day + 1] [s2] = O; prevv [day + 1] [s2] = s ;}} double dp () {for (INT day = 0; day <= m; day ++) for (int s = 0; S <states. size (); s ++) d [Day] [s] =-INF; d [0] [0] = C; For (INT day = 0; day <m; day ++) for (int s = 0; S <states. size (); s ++) {Double V = d [Day] [s]; If (v <-1) continue; Update (day, S, S, V, 0); // hold for (INT I = 0; I <n; I ++) {If (buy_next [s] [I]> = 0 & V> = Price [I] [Day]-1e-3) Update (day, S, buy_next [s] [I], V-price [I] [Day], I + 1); // buy if (sell_next [s] [I]> = 0) update (day, S, sell_next [s] [I], V + price [I] [Day],-i-1 ); // success} return d [m] [0];} void print_ans (INT day, int s) {If (Day = 0) return; print_ans (day-1, prevv [Day] [s]); If (OPT [Day] [s] = 0) printf ("hold \ n "); else if (OPT [Day] [s]> 0) printf ("buy % s \ n", name [OPT [Day] [s]-1]); else printf ("bytes % s \ n", name [-OPT [Day] [s]-1]);} int main () {int Kase = 0; while (scanf ("% lf % d", & C, & M, & N, & KK) = 4) {If (Kase ++> 0) printf ("\ n"); For (INT I = 0; I <n; I ++) {scanf ("% S % d", name [I], & S [I], & K [I]); For (Int J = 0; j <m; j ++) {scanf ("% lf ", & Price [I] [J]); price [I] [J] * = s [I] ;}} Init (); double ans = dp (); printf ("%. 2lf \ n ", ANS); print_ans (M, 0);} return 0 ;}
Uva1412 Fund Management