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;
} 

 

posted @ 2016-10-25 19:30  ACforever  阅读(226)  评论(0编辑  收藏  举报