BZOJ 1294 [SCOI2009]围豆豆Bean【】

1294: [SCOI2009]围豆豆Bean

Time Limit: 10 Sec   Memory Limit: 162 MB
Submit: 443   Solved: 299
[ Submit][ Status][ Discuss]

Description

Input

第一行两个整数N和M,为矩阵的边长。 第二行一个整数D,为豆子的总个数。 第三行包含D个整数V1到VD,分别为每颗豆子的分值。 接着N行有一个N×M的字符矩阵来描述游戏矩阵状态,0表示空格,#表示障碍物。而数字1到9分别表示对应编号的豆子。

Output

仅包含一个整数,为最高可能获得的分值。

Sample Input

3 8
3
30 -100 30
00000000
010203#0
00000000

Sample Output

38

设F[I][J][S]表示可以走到(i,j),吃到集合数为S的最短步数,枚举起点BFS。用射线法判断是否围住。


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 51210
int n,m,d,i,j,k,l,v[9],loc[9][2],S,ans,now;
int h,t,qx[N],qy[N],qk[N],f[11][11][513];
char a[12][12];
int cal(int px,int py,int x,int S){
  for(int i=0;i<d;i++)
  if(py<loc[i][1]&&(px==loc[i][0]&&x>loc[i][0]||px>loc[i][0]&&x==loc[i][0]))
    S^=1<<i;
  return S;
}
void add(int px,int py,int x,int y,int S,int w){
   if(a[x][y]!='0')return;
   S=cal(px,py,x,S);
   if(~f[x][y][S])return;
    f[x][y][S]=w;
    qx[++t]=x,qy[t]=y,qk[t]=S;
}
 void go(int x,int y,int S){
   add(x,y,x-1,y,S,f[x][y][S]+1);
   add(x,y,x+1,y,S,f[x][y][S]+1);
   add(x,y,x,y-1,S,f[x][y][S]+1);
   add(x,y,x,y+1,S,f[x][y][S]+1);
 }
 int main(){
    scanf("%d%d%d",&n,&m,&d);
    S=1<<d;
    for(i=0;i<d;i++)scanf("%d",&v[i]);
    for(i=0;i<=m+1;i++)a[0][i]=a[n+1][i]='#';
    for(i=1;i<=n;i++)a[i][0]=a[i][m+1]='#';
    for(i=1;i<=n;i++)for(scanf("%s",a[i]+1),j=1;j<=m;j++)
    if(a[i][j]!='0'&&a[i][j]!='#')loc[a[i][j]-'1'][0]=i,loc[a[i][j]-'1'][1]=j;
    for(i=1;i<=n;i++)for(j=1;j<=m;j++)if(a[i][j]=='0'){
    memset(f,-1,sizeof f);
    f[i][j][0]=0;
    qx[h=t=1]=i,qy[1]=j,qk[1]=0;
    while(h<=t)go(qx[h],qy[h],qk[h]),h++;
    for(k=0;k<S;k++)if(~f[i][j][k]){
    for(now=l=0;l<d;l++)if((k>>l)&1)now+=v[l];
    if(now-f[i][j][k]>ans)ans=now-f[i][j][k];
  }
 }
    printf("%d",ans);
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值