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终于过了。

  • 相关阅读:
    文件下载与中文文件名乱码问题解决
    文件字符编码的转换
    HTML速记
    MySQL学习笔记——安装
    C#防止重复弹出多个窗体
    ASP.NET Gridview中自带的日期格式设置功能
    [转]MSDTC on server '''' is unavailable. 的解决办法
    [转]关于SQL中Between语句查询日期的问题
    [转]SQL触发器实例讲解
    SQL索引技巧_1
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4750865.html
Copyright © 2011-2022 走看看