UVA 1412 Fund Management (预处理+状压dp)

时间:2023-03-09 08:49:43
UVA  1412 Fund Management (预处理+状压dp)

状压dp,每个状态可以表示为一个n元组,且上限为8,可以用一个九进制来表示状态。但是这样做用数组开不下,用map离散会T。

而实际上很多九进制数很多都是用不上的。因此类似uva 1601 Morning after holloween的思想,先dfs预处理出所有状态,用map将状态离散,

预处理出算出状态的转移DAG,而不是转移的时候在解码编码判断是否可行,然后一层一层bfs就行了。

附上测试数据

一层一层的bfs转移类似滚动数组,注意初始化(具体问题具体分析,有些问题没有必要做这一步)

一层一层的bfs,0.293s

#include<bits/stdc++.h>
using namespace std;
const int maxn = , maxm = ;
double c;
int m,n,K; const int maxlen = ;
char names[maxn][maxlen]; int k[maxn];
double price[maxn][maxm]; typedef vector<int> State;
vector<State> states;
#define PB push_back map<State,int> ID;
map<State,int>:: iterator it;
#define MP make_pair
#define fi first
#define se second const int maxst = ; State st;
void GetAllSta(int i)
{
if(i == n){
ID.insert(MP(st,states.size()));
states.PB(st);
return;
}
for(int j = ; j <= k[i] && st[n]+j <= K; j++){
st[i] = j;
st[n]+=j;
GetAllSta(i+);
st[n]-=j;
}
} int buy[maxst][maxn],sell[maxst][maxn]; void buildDAG()
{
st.resize(n+);
if(states.size()) states.clear();
ID.clear();
GetAllSta();
for(int s = ; s < states.size(); s++){
State &cur = states[s];
for(int i = ; i < n; i++){
buy[s][i] = sell[s][i] = -;
if(cur[i] < k[i] && cur[n] <K){
cur[i]++; cur[n]++;
buy[s][i] = ID[cur];
cur[i]--; cur[n]--;
}
if(cur[i]>){
cur[i]--; cur[n]--;
sell[s][i] = ID[cur];
cur[i]++; cur[n]++;
}
}
}
} double dp[][maxst];
int pre[maxm-][maxst];
int opt[maxm-][maxst]; void updata(int u,int v,double money,double *nxt,int day,int op,vector<int>* tomorrow)
{
if(nxt[v] < money ){
if(nxt[v] < -1.0){
tomorrow->PB(v);
}
opt[day][v] = op;
pre[day][v] = u;
nxt[v] = money; }
} vector<int> V1,V2;
void bfs()
{
V1.clear(); V2.clear();
int sz = states.size();
fill(dp[],dp[]+sz+,-);
vector<int>* today = &V1, *tomorrow = &V2;
today->PB(); dp[][] = c;
for(int day = ; day < m; day++){
double *const&cur = dp[day&], *const&nxt = dp[day&^];
fill(nxt,nxt+sz+,-);
int tsz = today->size();
for(int j = ; j < tsz; j++){
int s = (*today)[j];
double money = cur[s];
updata(s,s,money,nxt,day,,tomorrow);
for(int i = ; i < n; i++){
double stockPrice = price[i][day];
if(sell[s][i] >= ){
updata(s,sell[s][i],money+stockPrice,nxt,day,-i-,tomorrow);
}
if(buy[s][i] >= && money >= price[i][day] ){
updata(s,buy[s][i],money-stockPrice,nxt,day,i+,tomorrow);
}
}
}
swap(today,tomorrow);
tomorrow->clear();
}
} void read()
{
for(int i = ; i < n; i++){
int s; scanf("%s%d%d",names[i],&s,k+i);
for(int j = ; j < m; j++){
scanf("%lf",price[i]+j);
price[i][j] *= s;
}
}
} void print_ans()
{
int ans[maxm], u = ;
printf("%lf\n",max(dp[m&][u],dp[m&^][u]));
for(int i = m-; i >= ; i--){
ans[i] = opt[i][u];
u = pre[i][u];
}
for(int i = ; i < m; i++){
int t = ans[i];
if(t){
if(t>) printf("BUY %s\n",names[t-]);
else printf("SELL %s\n",names[-t-]);
}else puts("HOLD");
} } int main()
{
//freopen("in.txt","r",stdin);
while(~scanf("%lf%d%d%d",&c,&m,&n,&K)){
read();
buildDAG();
bfs();
print_ans();
}
return ;
}

直接按时间dp,0.199s

#include<bits/stdc++.h>
using namespace std;
const int maxn = , maxm = ;
double c;
int m,n,K; const int maxlen = ;
char names[maxn][maxlen]; int k[maxn];
double price[maxn][maxm]; typedef vector<int> State;
vector<State> states;
#define PB push_back map<State,int> ID;
map<State,int>:: iterator it;
#define MP make_pair
#define fi first
#define se second const int maxst = ; State st;
void GetAllSta(int i)
{
if(i == n){
ID.insert(MP(st,states.size()));
states.PB(st);
return;
}
for(int j = ; j <= k[i] && st[n]+j <= K; j++){
st[i] = j;
st[n] += j;
GetAllSta(i+);
st[n] -= j;
}
} int buy[maxst][maxn],sell[maxst][maxn]; void buildDAG()
{
st.resize(n+);
states.clear();
ID.clear();
GetAllSta();
for(int s = ; s < states.size(); s++){
State &cur = states[s];
for(int i = ; i < n; i++){
buy[s][i] = sell[s][i] = -;
if(cur[i] < k[i] && cur[n] < K){
cur[i]++; cur[n]++;
buy[s][i] = ID[cur];
cur[i]--; cur[n]--;
}
if(cur[i]>){
cur[i]--; cur[n]--;
sell[s][i] = ID[cur];
cur[i]++; cur[n]++;
}
}
}
} double d[][maxst];
int pre[maxm-][maxst];
int opt[maxm-][maxst]; void updata(int u,int v,double money,double *nxt,int day,int op)
{
if(nxt[v] < money){
nxt[v] = money;
opt[day][v] = op;
pre[day][v] = u;
}
} void dp()
{
int sz = states.size();
fill(d[],d[]+sz+,-);
d[][] = c;
for(int day = ; day < m; day++){
double *today = d[day&], (&tomorrow)[maxst] = d[(day&)^];
fill(tomorrow,tomorrow+sz+,-);
for(int s = ; s < sz; s++) {
double mon = today[s];
if(mon < -) continue;
updata(s,s,mon,tomorrow,day,);
for(int i = ; i < n; i++){
double val = price[i][day];
if(buy[s][i] >= && mon >= val){
updata(s,buy[s][i],mon-val,tomorrow,day,i+);
}
if(sell[s][i] >= ){
updata(s,sell[s][i],mon+val,tomorrow,day,-i-);
}
}
}
}
} void read()
{
for(int i = ; i < n; i++){
int s; scanf("%s%d%d",names[i],&s,k+i);
for(int j = ; j < m; j++) {
scanf("%lf",price[i]+j);
price[i][j] *= s;
}
}
} void print_ans()
{
int ans[maxm], u = ;
printf("%lf\n",d[m&][]);
for(int i = m-; i >= ; i--){
ans[i] = opt[i][u];
u = pre[i][u];
}
for(int i = ; i < m; i++){
int t = ans[i];
if(t){
if(t>) printf("BUY %s\n",names[t-]);
else printf("SELL %s\n",names[-t-]);
} else puts("HOLD");
} } int main()
{
//freopen("in.txt","r",stdin);
while(~scanf("%lf%d%d%d",&c,&m,&n,&K)){
read();
buildDAG();
dp();
print_ans();
}
return ;
}

附上1组测试数据

8765.43
EKXOU
497.60 572.49 777.30 798.74 856.42 907.12 951.80 973.32 997.39 428.54 285.77 21.88 15.36 11.55 6.48 5.64 4.73 0.35 0.10 511.06 825.53 961.92 962.12 989.97 994.93 996.52 997.17 999.80 999.87 124.40 60.90 27.93 16.15 1.18 0.49 0.08 0.01 0.01 0.01 482.35 502.45 689.55 894.80 943.09 968.54 978.27 981.05 990.68 998.48 180.68 51.73 10.82 1.58 1.41 1.35 1.00 0.91 0.09 0.07 264.18 389.68 861.28 924.38 930.49 987.65 994.23 994.57 997.81 998.38 0.09 0.04 0.03 0.03 0.02 0.02 0.02 0.01 0.01 0.01 764.88 784.31 881.75 979.84 995.53 995.88 999.45 999.50 999.50 999.88 51.96 41.72 0.31 0.08 0.02 0.02 0.02 0.02 0.01 0.01 783.83
TOJIX
337.36 798.61 959.78 974.23 974.66 980.52 985.75 988.00 997.75 202.70 22.45 9.80 9.75 1.37 1.25 0.08 0.07 0.01 0.01 453.79 956.23 974.28 975.82 984.13 997.62 998.44 999.34 999.55 999.70 720.60 279.71 263.45 125.87 19.68 2.05 0.34 0.19 0.18 0.09 956.28 983.92 998.93 999.21 999.49 999.94 999.95 999.97 999.98 999.99 420.16 201.90 171.95 105.75 55.79 5.57 2.35 0.29 0.26 0.07 287.31 833.57 923.40 973.86 989.51 996.69 998.67 999.51 999.76 999.96 592.20 253.01 135.07 47.59 36.20 20.77 4.27 2.15 2.08 0.41 824.65 844.61 914.04 946.35 986.53 993.71 998.21 999.08 999.74 999.81 31.97 6.57 0.89 0.87 0.28 0.06 0.06 0.06 0.04 0.02 543.05
YPBR
261.13 726.56 902.28 968.30 986.36 990.99 992.91 997.18 998.05 620.09 544.18 109.24 105.36 102.12 92.24 71.58 11.44 10.93 10.48 949.78 979.18 999.29 999.73 999.94 999.97 999.99 999.99 999.99 999.99 303.75 32.27 19.46 3.00 0.68 0.57 0.07 0.05 0.05 0.05 847.31 875.92 878.64 948.43 950.97 962.84 998.62 999.77 999.83 999.91 792.80 732.09 518.26 300.41 266.92 254.44 120.94 97.95 50.42 0.22 949.73 955.52 960.78 969.87 989.54 990.62 997.12 998.91 998.92 999.95 435.46 244.96 105.08 83.05 71.16 57.48 0.35 0.26 0.04 0.03 672.62 674.93 994.14 998.04 999.76 999.95 999.98 999.99 999.99 999.99 890.88 587.16 522.23 198.58 48.06 43.10 8.27 8.16 2.78 2.09 654.25
DMQHU
786.12 989.55 998.11 998.79 999.06 999.51 999.99 999.99 999.99 329.96 234.31 213.10 50.98 25.55 9.33 6.15 4.62 3.76 1.45 473.40 861.35 891.83 893.32 994.48 994.82 995.74 997.51 999.60 999.61 1.60 0.10 0.04 0.03 0.02 0.02 0.02 0.01 0.01 0.01 955.63 962.79 991.17 997.12 997.78 999.24 999.52 999.56 999.90 999.97 248.19 21.63 17.23 0.77 0.15 0.02 0.01 0.01 0.01 0.01 645.78 794.76 945.82 951.66 957.98 969.25 979.61 983.05 999.01 999.98 142.88 48.33 6.78 1.40 0.30 0.11 0.01 0.01 0.01 0.01 455.03 961.87 971.42 993.53 994.89 999.22 999.40 999.49 999.97 999.98 572.16 101.80 11.67 5.90 3.43 0.95 0.52 0.35 0.02 0.01 30.77
PA
171.57 814.60 880.12 930.74 999.37 999.85 999.94 999.95 999.99 616.08 337.98 275.98 268.51 144.13 73.64 9.64 5.77 3.64 1.16 635.71 887.63 942.64 973.01 988.12 988.27 997.58 998.96 999.49 999.63 595.22 61.20 54.08 45.03 30.42 15.34 1.37 1.13 0.27 0.13 315.10 713.86 918.35 924.16 934.51 946.22 986.08 991.68 997.52 997.85 910.50 385.99 38.53 23.88 9.77 4.83 1.56 1.12 1.08 0.59 798.72 925.88 991.50 994.57 999.42 999.45 999.74 999.96 999.96 999.98 409.21 306.84 13.02 5.35 1.71 1.09 0.05 0.05 0.01 0.01 461.25 580.76 659.42 820.34 934.58 979.96 983.33 993.69 995.64 996.48 217.36 102.03 55.09 1.02 0.07 0.04 0.03 0.01 0.01 0.01 756.52
GDXR
315.11 980.66 994.48 996.51 999.23 999.27 999.43 999.98 999.98 474.90 467.57 332.03 259.91 237.15 201.72 7.17 2.86 2.86 1.84 650.61 751.90 770.80 893.72 969.27 980.07 992.74 999.52 999.70 999.89 990.81 893.66 304.11 283.43 159.01 25.83 18.51 5.64 2.78 0.61 753.95 879.59 931.70 952.85 960.27 984.89 997.82 999.81 999.84 999.86 31.61 22.43 8.18 6.64 6.01 1.96 0.82 0.33 0.30 0.22 476.24 680.51 737.71 958.51 962.28 999.90 999.90 999.95 999.97 999.99 817.03 80.43 35.66 0.16 0.08 0.04 0.01 0.01 0.01 0.01 639.87 907.28 966.39 991.41 994.12 999.86 999.94 999.98 999.98 999.99 790.20 95.68 26.30 11.24 3.25 2.46 2.38 0.94 0.41 0.35 46.40
EHCN
36.99 751.66 794.23 984.85 991.56 995.68 995.84 998.77 999.24 362.81 331.16 56.41 47.53 3.28 3.26 2.10 0.46 0.05 0.04 426.68 789.10 883.32 972.42 982.25 992.18 999.99 999.99 999.99 999.99 861.04 780.38 1.12 0.05 0.05 0.01 0.01 0.01 0.01 0.01 822.44 874.05 974.89 978.78 999.96 999.96 999.98 999.99 999.99 999.99 237.58 43.68 32.98 19.61 7.45 2.53 1.39 0.88 0.65 0.23 55.26 638.65 727.28 832.58 995.85 999.88 999.95 999.95 999.99 999.99 447.03 329.97 247.45 31.78 1.85 1.56 1.38 1.29 1.21 1.14 863.62 954.56 981.69 982.01 986.16 991.74 998.82 999.49 999.52 999.54 586.70 151.55 104.38 71.89 5.38 2.25 0.78 0.48 0.19 0.06 11.43
LSEDH
678.83 957.20 975.00 999.45 999.97 999.98 999.98 999.98 999.98 785.99 712.30 476.84 87.14 36.88 25.14 10.90 1.70 1.04 0.04 799.70 983.34 992.55 993.58 994.11 994.86 996.95 998.88 999.82 999.85 759.48 560.12 180.82 61.18 40.45 10.25 6.36 5.09 3.91 1.43 955.45 993.56 993.96 999.00 999.69 999.88 999.90 999.96 999.98 999.99 165.77 144.71 54.31 40.19 27.33 26.45 3.48 0.85 0.29 0.16 119.74 760.63 976.18 987.90 996.92 999.90 999.95 999.96 999.96 999.98 357.32 175.40 7.05 2.21 1.42 0.82 0.57 0.07 0.07 0.01 648.07 833.15 972.96 993.92 996.42 999.70 999.75 999.75 999.79 999.92 917.38 168.10 152.48 61.59 33.33 19.03 10.88 2.79 2.65 2.23 509.18

测试数据的答案

298113.06
BUY EHCN
BUY EKXOU
BUY PA
SELL EHCN
BUY EKXOU
HOLD
SELL PA
SELL EKXOU
SELL EKXOU
HOLD
HOLD
BUY EKXOU
BUY EKXOU
BUY EHCN
BUY EKXOU
BUY EKXOU
BUY EHCN
BUY EKXOU
BUY EKXOU
HOLD
SELL EKXOU
BUY GDXR
SELL EHCN
SELL EKXOU
SELL EKXOU
SELL EHCN
SELL EKXOU
SELL EKXOU
SELL EKXOU
SELL GDXR
HOLD
BUY EHCN
BUY EHCN
BUY EKXOU
BUY EKXOU
BUY EKXOU
BUY EKXOU
BUY EKXOU
BUY EKXOU
SELL EHCN
BUY EKXOU
SELL EHCN
SELL EKXOU
SELL EKXOU
SELL EKXOU
SELL EKXOU
SELL EKXOU
SELL EKXOU
SELL EKXOU
HOLD
HOLD
BUY EKXOU
BUY EKXOU
BUY EKXOU
BUY EKXOU
BUY PA
BUY EHCN
BUY EKXOU
BUY EHCN
SELL PA
BUY EKXOU
SELL EKXOU
SELL EKXOU
SELL EHCN
SELL EHCN
SELL EKXOU
SELL EKXOU
SELL EKXOU
SELL EKXOU
HOLD
HOLD
BUY EKXOU
BUY EKXOU
BUY EKXOU
BUY EKXOU
BUY EKXOU
BUY EKXOU
BUY EHCN
BUY EHCN
SELL EHCN
BUY EKXOU
SELL EHCN
SELL EKXOU
SELL EKXOU
SELL EKXOU
SELL EKXOU
SELL EKXOU
SELL EKXOU
SELL EKXOU
HOLD
HOLD
HOLD
HOLD
HOLD
HOLD
HOLD
HOLD
HOLD
BUY EKXOU
SELL EKXOU

一开始想用dfs+回溯,T了,意识到dfs的话没有用到最优子结构的性质,用九进制+map离散保存状态dp,又T了,

改成预处理出DAG,然后bfs终于过了。