zoukankan      html  css  js  c++  java
  • tyvj1614 魔塔魔塔!

    描述

    百度noip贴吧管理组开发了一个小游戏,叫魔塔魔塔。虽然把魔塔重复了两次,但其实还只是个魔塔而已,还是简化版的。游戏在一个N*M大小的地图中进行,每一格都是正方形。
    对于某一格,有若干种可能的状态:
    1)空格,用“.”表示。人畜无害。
    2)陷阱,用“D”表示。踩一次会掉一些血,踩R次就会死亡。
    3)墙,用“#”表示。不能踩上这样的格子。
    4)宝物,用P表示。表示格子里有宝物,每个宝物都有一定的价值。同时宝物需要一些钥匙去开启,有三种不同的钥匙:红色、蓝色、绿色,每一个宝箱都需要最多三把钥匙打开。
    5)出生点,用“S”表示。

    现在你扮演着游戏中的勇者,正准备出发去购买宝物。一开始你有一些钱Q,你可以用这些钱向神秘商人Nettle购买一些红色、蓝色、绿色钥匙,价格分别是R,B,G。当你购买了钥匙后,就可以进入地图探险了,与此同时神秘商人Nettle就会离开,也就是说一旦进入地图,你就不能再购买钥匙了。一开始你在出生点,其中当你身上没有宝物时,你可以以1秒的时间从某个向上、下、左、右四个方向移动一格。当你遇到一个宝物,你可以选择拾起或不拾起(不浪费时间),但是一旦拾起就必须将其搬回游戏出生点,并且每步需要耗费3秒的时间。
    这个游戏有时间限制K秒。请你计算出在K秒内能获得的最大价钱。注意你一开始的金钱没有使用的部分也计算在内。

    输入格式

    输入第一行是五个数N,M,K,Q,R,表示地图的大小、时间限制、金钱数量和陷阱最多能踩的次数。(1<=N,M<=20,0<=K<=800,0<=Q<=100,0<=R<=10)
    之后是一个N*M的字符矩阵,表示地图上面的物品数量。
    之后是一行三个数R,B,G,表示红色、蓝色、绿色钥匙的价格。(1<=R,B,G<=100)
    之后是若干行(直至文件末尾EOF,你可以使用while(scanf()!=EOF)或者while not seekeof(input)读入),每行有六个数X,Y,A,B,C,V,表示在(x,y)处的宝箱需要A把红色钥匙B把蓝色钥匙C把绿色钥匙打开,价格为V。(0<=V<=5000,0<=A+B+C<=3)
    保证读入合法,并且只有一个S。

    输出格式

    输出只有一行,表示最多能获得的宝物价格。

    测试样例1

    输入

    5 5 10 100 1 
    ##### 
    #P#P# 
    #.#D# 
    #...# 
    ##S## 
    50 50 1 
    2 2 1 1 1 100 
    2 4 0 0 0 5000

    输出

    100
    /*
    bfs预处理,加一个背包dp,处理比较暴力,90分
    */
    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<queue>
    #include<vector>
    #define fo(i,l,r) for(int i = l;i <= r;i++)
    #define fd(i,l,r) for(int i = r;i >= l;i--)
    using namespace std;
    struct dat{
        int y;
        int x;
        int bl;
        int stp;
    };
    struct ITM{
        int x;
        int y;
        int r;
        int b;
        int g;
        int v;
    }itm[1005];
    int ans;
    int n,m,k,q,r,p_r,p_b,p_g;
    int am_p,am_t,sx,sy;
    int d[30][30][30];
    int dp[805][105][15];
    int dx[4] = {1,0,-1,0};
    int dy[4] = {0,-1,0,1};
    vector<int> mb[30][30];
    bool vis[30][30][30];
    char mp[30][30];
    inline bool judge(int y,int x){
        if(y > n||y < 1||x > m||x < 1||mp[y][x]=='#') return false;
        else return true;
    }
    inline int get_p(int t_r,int t_b,int t_g){
        return t_r*p_r + t_b*p_b + t_g*p_g;
    }
    int read(){
        int x=0,f=1;
        char ch=getchar();
        while(!(ch>='0'&&ch<='9')){if(ch=='-')f=-1;ch=getchar();};
        while(ch>='0'&&ch<='9'){x=x*10+(ch-'0');ch=getchar();};
        return x*f;
    }
    void input(){
        n = read();
        m = read();
        k = read();
        q = read();
        r = read();
        for(int i = 1;i <= n;i++) scanf("%s",mp[i]+1);
        fo(i,1,n){
            fo(j,1,m){
                if(mp[i][j] == 'S') sy = i,sx = j;
            }
        }
        p_r = read();
        p_b = read();
        p_g = read();
        int X,Y,A,B,C,V;
        while(scanf("%d%d%d%d%d%d",&X,&Y,&A,&B,&C,&V)!=EOF){
            am_p++;
            itm[am_p].y = X;
            itm[am_p].x = Y;
            itm[am_p].r = A;
            itm[am_p].b = B;
            itm[am_p].g = C;
            itm[am_p].v = V;
        }
    }
    void bfs(){
        dat now,to;
        queue<dat> q;
        now.y = sy;
        now.x = sx;
        now.bl = 0;
        now.stp = 0;
        q.push(now);
        vis[now.y][now.x][now.bl] = true;
        while(!q.empty()){
            now = q.front();
            q.pop();
            fo(k,0,3){
                to.y = now.y + dy[k];
                to.x = now.x + dx[k];
                if(!judge(to.y,to.x)) continue;
                to.bl = now.bl;
                to.stp = now.stp+1;
                if(mp[to.y][to.x] == 'D') to.bl++;
                if(to.bl > r) continue; 
                if(!vis[to.y][to.x][to.bl]){
                    vis[to.y][to.x][to.bl] = true;
                    d[to.y][to.x][to.bl] = to.stp;
                    mb[to.y][to.x].push_back(to.bl);
                    q.push(to);
                }
            }
        }
    }
    void get_ans(){
        int ny,nx,np,cta,ctb,ctm,get_m;
        fo(bx,1,am_p){
            ny = itm[bx].y;
            nx = itm[bx].x;
            get_m = itm[bx].v;
            if(!mb[ny][nx].size()) continue;
            fd(sj,1,k){
                fd(jq,1,q){
                    np = get_p(itm[bx].r,itm[bx].b,itm[bx].g);
                    if(jq < np) break;
                    fd(xl,1,r){
                        fo(sxl,0,mb[ny][nx].size()-1){
                            fo(sxh,0,mb[ny][nx].size()-1){
                                cta = mb[ny][nx][sxl];
                                ctb = mb[ny][nx][sxh];    
                                ctm = d[ny][nx][cta] + 3*d[ny][nx][ctb];
                                if(xl < cta + ctb) continue;
                                if(sj < ctm) continue;
                                dp[sj][jq][xl] = max(dp[sj][jq][xl],dp[sj-ctm][jq-np][xl-cta-ctb] + get_m - np);
                                ans = max(dp[sj][jq][xl],ans);
                                
                            }
                        }
                    }
                }
            }
        }
        cout<<ans + q;
    }
    int main(){
        input();
        bfs();
        get_ans();
        return 0;
    } 
  • 相关阅读:
    Java版本及历史简述
    ASCII、Unicode、UTF-8、UTF-16、GBK、GB2312、ANSI等编码方式简析
    同步(Synchronous)和异步(Asynchronous)方法的区别
    例10-12 *uva1637(概率dp)
    例10-11 uva11181
    例10-10 uva10491(简单概率)
    例10-9 uva1636简单概率问题
    全排列hash-康拓展开
    10-8 uva1262密码
    例10-6 uva1635(唯一分解定理)
  • 原文地址:https://www.cnblogs.com/hyfer/p/5997926.html
Copyright © 2011-2022 走看看