状压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 = 8, maxm = 105; double c; int m,n,K;const int maxlen = 10; char names[maxn][maxlen];int k[maxn]; double price[maxn][maxm];typedef vector<int> State; vector<State> states; #define PB push_backmap<State,int> ID; map<State,int>:: iterator it; #define MP make_pair #define fi first #define se secondconst int maxst = 13000;State st; void GetAllSta(int i) {if(i == n){ID.insert(MP(st,states.size()));states.PB(st);return;}for(int j = 0; j <= k[i] && st[n]+j <= K; j++){st[i] = j;st[n]+=j;GetAllSta(i+1);st[n]-=j;} }int buy[maxst][maxn],sell[maxst][maxn];void buildDAG() {st.resize(n+1);if(states.size()) states.clear();ID.clear();GetAllSta(0);for(int s = 0; s < states.size(); s++){State &cur = states[s];for(int i = 0; i < n; i++){buy[s][i] = sell[s][i] = -1;if(cur[i] < k[i] && cur[n] <K){cur[i]++; cur[n]++;buy[s][i] = ID[cur];cur[i]--; cur[n]--;}if(cur[i]>0){cur[i]--; cur[n]--;sell[s][i] = ID[cur];cur[i]++; cur[n]++;}}} }double dp[2][maxst]; int pre[maxm-4][maxst]; int opt[maxm-4][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[0],dp[0]+sz+1,-666);vector<int>* today = &V1, *tomorrow = &V2;today->PB(0); dp[0][0] = c;for(int day = 0; day < m; day++){double *const&cur = dp[day&1], *const&nxt = dp[day&1^1];fill(nxt,nxt+sz+1,-666);int tsz = today->size();for(int j = 0; j < tsz; j++){int s = (*today)[j];double money = cur[s];updata(s,s,money,nxt,day,0,tomorrow);for(int i = 0; i < n; i++){double stockPrice = price[i][day];if(sell[s][i] >= 0){updata(s,sell[s][i],money+stockPrice,nxt,day,-i-1,tomorrow);}if(buy[s][i] >= 0 && money >= price[i][day] ){updata(s,buy[s][i],money-stockPrice,nxt,day,i+1,tomorrow);}}}swap(today,tomorrow);tomorrow->clear();} }void read() {for(int i = 0; i < n; i++){int s; scanf("%s%d%d",names[i],&s,k+i);for(int j = 0; j < m; j++){scanf("%lf",price[i]+j);price[i][j] *= s;}} }void print_ans() {int ans[maxm], u = 0;printf("%lf\n",max(dp[m&1][u],dp[m&1^1][u]));for(int i = m-1; i >= 0; i--){ans[i] = opt[i][u];u = pre[i][u];}for(int i = 0; i < m; i++){int t = ans[i];if(t){if(t>0) printf("BUY %s\n",names[t-1]);else printf("SELL %s\n",names[-t-1]);}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 0; }
直接按时间dp,0.199s
#include<bits/stdc++.h> using namespace std; const int maxn = 8, maxm = 105; double c; int m,n,K;const int maxlen = 10; char names[maxn][maxlen];int k[maxn]; double price[maxn][maxm];typedef vector<int> State; vector<State> states; #define PB push_backmap<State,int> ID; map<State,int>:: iterator it; #define MP make_pair #define fi first #define se secondconst int maxst = 13000;State st; void GetAllSta(int i) {if(i == n){ID.insert(MP(st,states.size()));states.PB(st);return;}for(int j = 0; j <= k[i] && st[n]+j <= K; j++){st[i] = j;st[n] += j;GetAllSta(i+1);st[n] -= j;} }int buy[maxst][maxn],sell[maxst][maxn];void buildDAG() {st.resize(n+1);states.clear();ID.clear();GetAllSta(0);for(int s = 0; s < states.size(); s++){State &cur = states[s];for(int i = 0; i < n; i++){buy[s][i] = sell[s][i] = -1;if(cur[i] < k[i] && cur[n] < K){cur[i]++; cur[n]++;buy[s][i] = ID[cur];cur[i]--; cur[n]--;}if(cur[i]>0){cur[i]--; cur[n]--;sell[s][i] = ID[cur];cur[i]++; cur[n]++;}}} }double d[2][maxst]; int pre[maxm-4][maxst]; int opt[maxm-4][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[0],d[0]+sz+1,-666);d[0][0] = c;for(int day = 0; day < m; day++){double *today = d[day&1], (&tomorrow)[maxst] = d[(day&1)^1];fill(tomorrow,tomorrow+sz+1,-233);for(int s = 0; s < sz; s++) {double mon = today[s];if(mon < -1) continue;updata(s,s,mon,tomorrow,day,0);for(int i = 0; i < n; i++){double val = price[i][day];if(buy[s][i] >= 0 && mon >= val){updata(s,buy[s][i],mon-val,tomorrow,day,i+1);}if(sell[s][i] >= 0){updata(s,sell[s][i],mon+val,tomorrow,day,-i-1);}}}} }void read() {for(int i = 0; i < n; i++){int s; scanf("%s%d%d",names[i],&s,k+i);for(int j = 0; j < m; j++) {scanf("%lf",price[i]+j);price[i][j] *= s;}} }void print_ans() {int ans[maxm], u = 0;printf("%lf\n",d[m&1][0]);for(int i = m-1; i >= 0; i--){ans[i] = opt[i][u];u = pre[i][u];}for(int i = 0; i < m; i++){int t = ans[i];if(t){if(t>0) printf("BUY %s\n",names[t-1]);else printf("SELL %s\n",names[-t-1]);} 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 0; }
附上1组测试数据
8765.43 100 8 8 EKXOU 8 8 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 4 7 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 1 4 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 3 5 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 4 5 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 5 5 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 10 2 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 5 1 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终于过了。