福大3月月賽 魔塔

來源:互聯網
上載者:User

轉載請註明出處,謝謝http://blog.csdn.net/ACM_cxlove?viewmode=contents           by---cxlove

http://acm.fzu.edu.cn/problem.php?pid=2073

又是一個神題,給出一個n*m的圖,上面有若干個怪,每個怪有一定的血,攻擊,防禦,以及攻擊獎勵,防禦獎勵。
玩過魔塔的童鞋應該很清楚,每打一個怪,消滅他,可以獲得一定的攻擊防禦獎勵,消滅所有的怪,就算成功了。
此題是外掛摸式,無限血,不過也存在無法過關的情況,求消滅所有的怪,受到的最少傷害。
想當年cxlove通關救出了公主,哈哈。
處理起來很麻煩,首先枚舉所有的怪為起點,bfs找可以到達的其它怪,鄰接陣儲存。

之後是狀態DP,dp[i][j],表示當前位置為i,目前狀態為j。

/*ID:cxlovePROB:FJU2073魔塔DATA:2012.3.27-3.28HINT:bfs+狀態DP*/#include<iostream>#include<cstdio>#include<cstring>#include<vector>#define inf 1<<30using namespacestd;struct Node{    inthp,attack,defense,award_attack,award_defense;    //怪的血量,攻擊,防禦,攻擊獎勵,防禦獎勵}monster[11];struct Point{    int x,y;}s,que[500*500+10];struct Monster{    Point pos;    int kind;     //記錄地圖上怪獸的位置和怪物種類}Map[11];char str[505][505];int cnt;//怪獸的個數int n,m,p;int mat[15][15];bool flag[505][505];int way[4][2]={{0,1},{0,-1},{1,0},{-1,0}};int dp[11][1<<10]; //dp[i][j]表示目前處在第i個怪物的位置,已殺怪物的狀態為j時的最少傷害void bfs(int k){    Point p;    inthead=0,tail=0;    que[tail++]=Map[k].pos;    flag[que[0].x][que[0].y]=true;    while(head<tail){        p=que[head++];             for(int i=0;i<4;i++){            Point pp;            pp.x=p.x+way[i][0];            pp.y=p.y+way[i][1];            if(str[pp.x][pp.y]!='*'&&pp.x>=0&&pp.x<n&&pp.y>=0&&pp.y<m&&flag[pp.x][pp.y]==false){                if(str[pp.x][pp.y]=='.')                    que[tail++]=pp;                else{                   for(int j=1;j<=cnt;j++)                        if(pp.x==Map[j].pos.x&&pp.y==Map[j].pos.y)                            mat[k][j]=1;                }                flag[pp.x][pp.y]=true;            }        }    }}int check(int state,int k){    intper_attack=10,per_deffense=10;    //初始攻擊,防禦    for(int i=0;i<cnt;i++)        if((1<<i)&state){            intkind=Map[i+1].kind;            per_attack=min(50,monster[kind].award_attack+per_attack);            per_deffense=min(50,monster[kind].award_defense+per_deffense);        }      intkind=Map[k].kind;   /*cout<<per_attack<<""<<per_deffense<<endl;*/    if(per_attack<=monster[kind].defense)        return-1;    if(per_deffense>=monster[kind].attack)        return0;    inthp=monster[kind].hp,a1=per_attack,d1=monster[kind].defense,a2=monster[kind].attack,d2=per_deffense;    return(hp/(a1-d1)+(hp%(a1-d1)==0?-1:0))*(a2-d2);}int sum[1<<10];vector<int>status[11];int main(){    sum[0]=0;    for(int i=1;i<(1<<10);i++){        sum[i]=sum[i>>1]+(i&1);        status[sum[i]].push_back(i);    }    while(scanf("%d%d%d",&n,&m,&p)!=EOF){        cnt=0;        for(int i=1;i<=p;i++)            scanf("%d%d%d%d%d",&monster[i].hp,&monster[i].attack,&monster[i].defense,&monster[i].award_attack,&monster[i].award_defense);        for(int i=0;i<n;i++){            scanf("%s",str[i]);            for(int j=0;j<m;j++)                if(str[i][j]=='#'){                    s.x=i;                    s.y=j;                }                elseif(str[i][j]>='1'&&str[i][j]<='9'){                    cnt++;                    Map[cnt].pos.x=i;                    Map[cnt].pos.y=j;                    Map[cnt].kind=str[i][j]-'0';                }        }        Map[0].pos=s;Map[0].kind=0;        memset(mat,0,sizeof(mat));        for(int i=0;i<=cnt;i++){            memset(flag,false,sizeof(flag));            bfs(i);        }        /*for(inti=0;i<=cnt;i++){            for(int j=0;j<=cnt;j++)                printf("%d  ",mat[i][j]);            printf("\n");        }*/        for(int i=0;i<=cnt;i++)            for(int j=0;j<(1<<cnt);j++)                dp[i][j]=inf;        dp[0][0]=0;        for(int i=1;i<=cnt;i++){            if(mat[0][i]){                inttemp=check(0,i);                if(temp<0)                    continue;                dp[i][1<<(i-1)]=temp;            }        }        /*for(inti=1;i<=cnt;i++)           if(dp[i][1<<(i-1)]!=inf)                printf("%d%d\n",i,dp[i][1<<(i-1)]);*/        for(int i=1;i<cnt;i++){            for(int j=0;j<status[i].size();j++){               intJ=status[i][j];                for(int k=1;k<=cnt;k++){                                   //dp[k][J]                    if(((1<<(k-1))&J)&&dp[k][J]!=inf){                        for(int r=1;r<=cnt;r++){                            if(mat[k][r]&&k!=r&&((1<<(r-1))&J)==0){                                                        int temp=check(J,r);                                                           /*cout<<k<<" "<<J<<""<<r<<" "<<temp<<endl;                                system("pause");*/                                if(temp<0)                                    continue;                                                          dp[r][J|(1<<(r-1))]=min(dp[r][J|(1<<(r-1))],dp[k][J]+temp);                                for(intrr=1;rr<=cnt;rr++)//注意!!!BFS的時候狀態是在原圖未消滅一個怪的前提下,注意更新後的情況                                    if(J&(1<<(rr-1)))                                        dp[rr][J|(1<<(r-1))]=min(dp[rr][J|(1<<(r-1))],dp[r][J|(1<<(r-1))]);                            }                        }                    }                }            }        }        int ans=inf;        for(int i=1;i<=cnt;i++)            ans=min(ans,dp[i][(1<<cnt)-1]);        if(ans==inf)            printf("-1\n");        else            printf("%d\n",ans);    }    return 0;}/*1313 61012 2 2 1202 2 2 33013 3 1 14014 4 1 15011 5 1 16028 6 1 1**************..121......************.**.....*...*.**.5.*.*...*.***.**.***.*.**...*..343*.**.6.*.*****.***.**.......**...**.***.***...*...*.3.**...*.#.*1..**************513 21012 2 2 1202 2 2 3**************..121......************.**...#.*...*.***************/

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.