zoukankan      html  css  js  c++  java
  • Bzoj1294 [SCOI2009]围豆豆Bean

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 412  Solved: 276

    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

    HINT

    50%的数据满足1≤D≤3。
    100%的数据满足1≤D≤9,1≤N, M≤10,-10000≤Vi≤10000。

    Source

    数学 几何 状态压缩 BFS

    从一点向随机方向引一条射线,如果射线和多边形的边相交奇数次,说明点在多边形内。

    据此我们可以搞D条射线出来,用来判断D个点当前是否已经被圈进来。

    f[x][y][圈进的豆豆集合S]=最小花费

    状压BFS,在搜索过程中即时更新点被圈的状态,方便剪枝(暴力搜完再判断收益会T)

    写了SPFA,差不多一个意思

      1 /*by SilverN*/
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<cstring>
      5 #include<cstdio>
      6 #include<cmath>
      7 #include<vector>
      8 #include<queue>
      9 using namespace std;
     10 const int mx[5]={0,0,1,0,-1};
     11 const int my[5]={0,1,0,-1,0};
     12 const int INF=0x3f3f3f3f;
     13 const int mxn=100010;
     14 int read(){
     15     int x=0,f=1;char ch=getchar();
     16     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     17     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
     18     return x*f;
     19 }
     20 struct point{
     21     int cx,cy;//
     22     int x,y;//向量 
     23     point operator + (point b){return (point){x+b.x,y+b.y};}
     24     point operator - (point b){return (point){x-b.x,y-b.y};}
     25     int operator * (point b){return x*b.x+y*b.y;}
     26 };
     27 typedef point Vector;
     28 Vector b[mxn];
     29 double Cross(point a,point b){
     30     return a.x*b.y-a.y*b.x;
     31 }
     32 int n,m,D;
     33 int Segcross(int x,int y,int nx,int ny,int S){
     34     for(int i=1;i<=D;i++){
     35         if(( (x<b[i].cx && nx>=b[i].cx)||(x>=b[i].cx && nx<b[i].cx) )&& y>b[i].cy){
     36             S^=1<<(i-1);
     37         }
     38     }
     39     return S;
     40 }
     41 int w[mxn];
     42 char mp[12][12];
     43 struct node{int i,j,S;};
     44 int f[12][12][1<<9],ans;
     45 bool inq[12][12][1<<9];
     46 void SPFA(int sx,int sy){
     47     queue<node>q;
     48     q.push((node){sx,sy,0});
     49     memset(f,0x3f,sizeof f);
     50     f[sx][sy][0]=0;
     51     while(!q.empty()){
     52         node u=q.front();q.pop();
     53         inq[u.i][u.j][u.S]=0;
     54         for(int k=1;k<=4;k++){
     55             int nx=u.i+mx[k],ny=u.j+my[k];
     56             if(nx>0 && nx<=n && ny>0 && ny<=m){
     57                 if(mp[nx][ny]!='0')continue;
     58                 int s=Segcross(u.i,u.j,nx,ny,u.S);
     59                 if(f[nx][ny][s]>f[u.i][u.j][u.S]+1){
     60                     f[nx][ny][s]=f[u.i][u.j][u.S]+1;
     61                     inq[nx][ny][s]=1;
     62                     q.push((node){nx,ny,s});
     63                 }
     64             }
     65         }
     66     }
     67     int ed=1<<D;
     68 //  printf("sx:%d sy:%d
    ",sx,sy);
     69     for(int i=0;i<ed;i++){
     70 //      printf("S:%d  f:%d
    ",i,f[sx][sy][i]);
     71         int res=-f[sx][sy][i];
     72         for(int j=1;j<=D;j++){
     73             if(i&(1<<(j-1)))res+=w[j];
     74         }
     75         ans=max(ans,res);
     76     }
     77     return;
     78 }
     79 int main(){
     80 //  freopen("in.txt","r",stdin);
     81     int i,j;
     82     n=read();m=read();D=read();
     83     for(i=1;i<=D;i++)w[i]=read();
     84     for(i=1;i<=n;i++){
     85         scanf("%s",mp[i]+1);
     86         for(j=1;j<=m;j++){
     87             if(mp[i][j]>'0' && mp[i][j]<='9'){
     88                 int x=mp[i][j]-'0';
     89                 b[x]=(Vector){i,j,0,j+100};
     90             }
     91         }
     92     }
     93 /*  for(i=1;i<=D;i++){
     94         printf("%d %d %d %d
    ",b[i].cx,b[i].cy,b[i].x,b[i].y);
     95     }*/
     96     //
     97     for(i=1;i<=n;i++)
     98         for(j=1;j<=m;j++)
     99             if(mp[i][j]=='0'){
    100                 SPFA(i,j);
    101             }
    102     printf("%d
    ",ans);
    103     return 0;
    104 }
  • 相关阅读:
    简单实现 C# 与 Javascript的兼容
    如何写好CSS系列之表单(form)
    D3、openlayers的一次尝试
    如何写好css系列之button
    mockjs,json-server一起搭建前端通用的数据模拟框架
    AIX中的/etc/inittab文件
    AIX中crontab和at 定时任务
    AIX中的服务管理
    AIX系统的备份和恢复
    AIX中磁带设备的使用
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6668935.html
Copyright © 2011-2022 走看看