zoukankan      html  css  js  c++  java
  • 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 = 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_back
    
    map<State,int> ID;
    map<State,int>:: iterator it;
    #define MP make_pair
    #define fi first
    #define se second
    
    const 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
    ",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
    ",names[t-1]);
                else printf("SELL %s
    ",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;
    }
    View Code

    直接按时间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_back
    
    
    map<State,int> ID;
    map<State,int>:: iterator it;
    #define MP make_pair
    #define fi first
    #define se second
    
    const 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
    ",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
    ",names[t-1]);
                else printf("SELL %s
    ",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;
    }
    View Code

    附上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
    View Code

    测试数据的答案

    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
    View Code

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

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

  • 相关阅读:
    方法重写
    百度地图(5)-添加标注
    百度地图(3)-添加地图控件
    百度地图(2)-初始化地图
    GIS系统开发流程
    百度地图(1)- JavaScript API V3.0 对比 JavaScript GL API 1.0
    通过QGIS下载OSM数据
    深入理解 Spring 之源码剖析IOC
    FastDFS安装教程
    FastDFS简介
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4750865.html
Copyright © 2011-2022 走看看