Link:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem= 4158
Test instructions
You have C (0.01≤c≤1e8) dollars in cash but no stock. Give you M (1≤m≤100) days time and N (1≤n≤8) stock for you to trade,
Requires no stock at the end of the last day and the most money left. The stock is not on credit and can only be bought in cash.
The daily price of each stock is known (0.01~999.99. Units are USD/shares) with parameters Si and Ki,
The stock is SI (1≤si≤1e6) shares, and the number of hands held per day cannot exceed Ki (1≤ki≤k), where k is the total number of lots held per day.
Either do not operate every day, or choose a stock, buy or sell its one-hand stock. Both C and share prices contain up to two decimal places (i.e. cents).
The optimal solution is guaranteed to be no more than 1e9. A decision is required to output every day (hold means no change, sell means sell, buy indicates purchase).
Analysis:
use D (i,p) to indicate the maximum value of cash when the asset combination is p after I days. where P is an n-tuple, Pi≤ki indicates that the first stock has pi hands.
according to the title, P1+...+pn≤k. Because 0≤pi≤8, there are theoretically only 9^8<5e7 possible, so you can use a nine-way integer to represent p.
there are altogether 3 decisions: Hold, buy and sell, respectively.
Note When considering buying a stock, don't forget to judge whether the cash you currently have is sufficient.
However, this is not efficient enough, because the nine-ary integer cannot be directly "buy and sell stock" operation, need to decode into N-tuple.
because almost every state transition involves encoding and decoding, the time for state transitions is significantly increased, resulting in timeouts.
The workaround is to calculate all possible states and numbers in advance, and then construct a State transfer table,
The status number that is transferred to the "Buy stock I" and "Sell stock I", respectively, using buy[s][i] and sell[s][i].
The dynamic Programming main program uses the Brush table method, in order to be convenient, has also written "The update state" the function update.
in order to print the solution, the optimal policy opt and "last state" F are updated when the solution D is updated.
Note that the price[i][day in the code] represents the price of the first-hand stock I, not the "price per share" in the input.
Finally, the part that prints the solution. Since the state is defined from the front to the back, the printing solution needs to be printed from the back to the front, which is convenient with recursion.
Code:
1#include <cstdio>2#include <map>3#include <vector>4 using namespacestd;5 6typedefLong Long intLLI;7 ConstLLI INF =0x3f3f3f3f3f3f3f3f;8 Const intUPM = -+5;9 Const intUPN =8+5;Ten Const intUPS =15000; One intm, N, KK, K[UPN]; A intBUY[UPS][UPN], SELL[UPS][UPN], f[upm][ups], opt[upm][ups]; - LLI C, PRICE[UPN][UPM], d[upm][ups]; - Charname[upn][5+5]; thevector<vector<int> >State ; -map<vector<int,int>ID; - - voidDfsintStock, vector<int>& V,inttot) { + if(Stock = =N) { -ID[V] =state.size (); + State.push_back (V); A return; at } - for(inti =0; I <= K[stock] && tot+i <= KK; i++) { -V[stock] =i; -DFS (stock+1, V, tot+i); - } - } in - voidinit () { to state.clear (); + id.clear (); -vector<int>V (n); theDfs0V0); * for(ints =0; s < state.size (); s++) { $ inttot =0;Panax Notoginseng for(inti =0; I < n; i++) Tot + =State[s][i]; - for(inti =0; I < n; i++) { theBuy[s][i] = sell[s][i] =-1; + if(State[s][i] < k[i] && tot <KK) { AV =State[s]; thev[i]++; +Buy[s][i] =Id[v]; - } $ if(State[s][i] >0) { $V =State[s]; -v[i]--; -Sell[s][i] =Id[v]; the } - }Wuyi } the } - Wu voidUpdateintDayintSintS2, LLI V,into) { - if(d[day+1][S2] >= v)return; Aboutd[day+1][S2] =v; $f[day+1][S2] =s; -opt[day+1][S2] =o; - } - A LLI dynamicprogramming () { + for(inti =0; I <= m; i++) the for(ints =0; s < state.size (); s++) D[i][s] =-INF; -d[0][0] =C; $ for(intDay =0; Day < M; day++) { the for(ints =0; s < state.size (); s++) { theLLI v =D[day][s]; the if(V <-1)Continue; theUpdate (day, S, S, V,0); - for(inti =0; I < n; i++) { in if(Buy[s][i] >=0&& V-price[i][day] >=0) theUpdate (day, S, Buy[s][i], V-price[i][day], i+1); the if(Sell[s][i] >=0) AboutUpdate (day, S, Sell[s][i], V+price[i][day],-(i+1)); the } the } the } + returnd[m][0]; - } the Bayi voidOutputintDayints) { the if(Day = =0)return; theOutput (day-1, F[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]); the Elseprintf"SELL%s\n", name[-opt[day][s]-1]); the } the the intMain () { - Doubletemp; the intLot, cases =0; the while(~SCANF ("%lf%d%d%d", &temp, &m, &n, &KK)) { thec = (temp + 1e-3) * -;94 for(inti =0; I < n; i++) { thescanf"%s%d%d", Name[i], &lot, &k[i]); the for(intt =0; T < m; t++) { thescanf"%LF", &temp);98Price[i][t] = (LLI) (temp + 1e-3) * -) *Lot ; About } - }101 init ();102LLI ans =dynamicprogramming ();103 if(cases++ >0) printf ("\ n");104printf"%lld.%0 2lld\n", ans/ -, ans% -); theOutput (M,0);106 }107 return 0;108}
UVa 1412-fund Management (pressure DP + pretreatment)