BZOJ 1294 [SCOI2009]围豆豆Bean ——计算几何

显然我们不可能表示出一台路径,因为实在是太复杂了。

所以我们可以记录一下路径对答案的影响,显然路径对答案影响相同的时候,答案更优,所以我们可以用影响来代替路径。

所以我们考虑状压一下所有的豆子有没有被围起来,然后判定的方法是随便引出一条射线,判断和多边形的交点的个数,我们只需要记录奇偶性,所以直接状压即可。

然后枚举起点,宽度优先搜索处理之后,计算所有影响下的最优答案即可。

为了方便转移,我们选择豆子向上偏右的方向的射线作为判断。

#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define ll long long
#define mp make_pair
 
int v[10],n,m,d,ret=0;
int dis[11][11][1<<10];
char s[20];
int map[12][12],x[10],y[10];
int mov[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
queue <int> qx,qy,qs;
 
void print(int x)
{
    F(i,0,d-1) printf("%d",(x>>i)&1);
}
 
int main()
{
    scanf("%d%d%d",&n,&m,&d);
    F(i,0,d-1) scanf("%d",&v[i]);
    F(i,1,n)
    {
        scanf("%s",s+1);
        F(j,1,m)
        {
            switch(s[j])
            {
                case '0': map[i][j]=0;break;
                case '#': map[i][j]=-1;break;
                default:x[s[j]-'1']=i;y[s[j]-'1']=j;map[i][j]=-1;break;
            }
        }
    }
//  F(i,0,d-1) printf("Bean (%d,%d)\n",x[i],y[i]);
    F(i,0,m+1) map[0][i]=map[n+1][i]=-1;
    F(i,0,n+1) map[i][0]=map[i][m+1]=-1;
//  F(i,0,n+1) F(j,0,m+1) printf("%5d%c",map[i][j],j==m+1?'\n':' ');
    F(sx,1,n) F(sy,1,m)
    {
        memset(dis,0x3f,sizeof dis);
        qx.push(sx);qy.push(sy);qs.push(0);dis[sx][sy][0]=0;
        while (!qx.empty())
        {
            int nx=qx.front(),ny=qy.front(),ns=qs.front();
//          printf("now is %d %d ",nx,ny); print(ns); printf("\n");
            qx.pop();qy.pop();qs.pop();
            if (nx==sx&&ny==sy)
            {
                int ans=-dis[nx][ny][ns];
                F(i,0,d-1) if (ns&(1<<i)) ans+=v[i];
                ret=max(ret,ans);
            }
            F(k,0,3)
            {
                int tx=nx+mov[k][0],ty=ny+mov[k][1];
//              printf("(%d,%d) to (%d,%d) k is %d\n",nx,ny,tx,ty,k);
                if (map[tx][ty]!=-1)
                {
                    int ts=ns;
                    F(i,0,9)
                    {
                        if ((k==0&&(ty==y[i]+1&&tx<x[i]))
                          ||(k==1&&(ty==y[i]&&tx<x[i])))
                            {
//                              printf("go %d\n",i);
                                ts^=1<<i;
                            }
//                      printf("Bea %d %d\n",x[i],y[i]);
                    }
//                  print(ts); printf("\n");
                    if (dis[tx][ty][ts]>dis[nx][ny][ns]+1)
                    {
                        dis[tx][ty][ts]=dis[nx][ny][ns]+1;
                        qx.push(tx);qy.push(ty);qs.push(ts);
                    }
                }
            }
        }
    }
    printf("%d\n",ret);
}

  

posted @ 2017-04-09 19:51  SfailSth  阅读(185)  评论(0编辑  收藏  举报