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

    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。

    正解:计算几何+状压$dp$+$spfa$。

    这题的难点就在于如何判断一个豆子是否在多边形内。

    实际上有一个很好判断的方法,那就是可以引一条水平线,看和多边形有几个交点,有奇数个交点就在多边形内,否则在多边形外。

    但是还有一个情况。就是如果路径从上往下,突然往水平拐,再往下拐,那么这是有偶数个交点的,但是豆子还是在多边形内。

    不过我们可以把所有边当成上开下闭的边,只有当水平线与一条边的下端点相交才算进去。

    然后我们可以直接写一个状压+$spfa$。

     1 #include <bits/stdc++.h>
     2 #define il inline
     3 #define RG register
     4 #define ll long long
     5 #define inf (1<<29)
     6 
     7 using namespace std;
     8 
     9 struct data{ int x,y,bin; }p[15];
    10 
    11 const int d1[4]={0,0,-1,1};
    12 const int d2[4]={-1,1,0,0};
    13 
    14 int f[15][15][1<<12],vis[15][15][1<<12],g[15][15],val[15],S,n,m,all,ans;
    15 
    16 queue<data> Q;
    17 
    18 il int gi(){
    19   RG int x=0,q=1; RG char ch=getchar();
    20   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    21   if (ch=='-') q=-1,ch=getchar();
    22   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    23   return q*x;
    24 }
    25 
    26 il char gc(){
    27   RG char ch=getchar();
    28   while ((ch<'0' || ch>'9') && ch!='#') ch=getchar();
    29   return ch;
    30 }
    31 
    32 il void spfa(RG int sx,RG int sy){
    33   for (RG int i=1;i<=n;++i)
    34     for (RG int j=1;j<=m;++j)
    35       for (RG int k=0;k<all;++k) f[i][j][k]=-inf;
    36   Q.push((data){sx,sy,0}),f[sx][sy][0]=0,vis[sx][sy][0]=1;
    37   while (!Q.empty()){
    38     RG data now=Q.front(); Q.pop();
    39     if (now.x==sx && now.y==sy)
    40       ans=max(ans,f[now.x][now.y][now.bin]);
    41     for (RG int k=0,x,y,yy,bin,del;k<4;++k){
    42       x=now.x+d1[k],y=now.y+d2[k];
    43       if (x<=0 || x>n || y<=0 || y>m || g[x][y]) continue;
    44       bin=now.bin,yy=max(y,now.y),del=0;
    45       if (k<=1){
    46     for (RG int i=1;i<=S;++i)
    47       if (p[i].y==yy && p[i].x<x){
    48         bin^=1<<(i-1);
    49         if (bin>>(i-1)&1) del+=val[i]; else del-=val[i];
    50       }
    51       }
    52       if (f[x][y][bin]<f[now.x][now.y][now.bin]+del-1){
    53     f[x][y][bin]=f[now.x][now.y][now.bin]+del-1;
    54     if (!vis[x][y][bin]) vis[x][y][bin]=1,Q.push((data){x,y,bin});
    55       }
    56     }
    57     vis[now.x][now.y][now.bin]=0;
    58   }
    59   return;
    60 }
    61 
    62 int main(){
    63 #ifndef ONLINE_JUDGE
    64   freopen("bean.in","r",stdin);
    65   freopen("bean.out","w",stdout);
    66 #endif
    67   n=gi(),m=gi(),S=gi(),all=1<<S;
    68   for (RG int i=1;i<=S;++i) val[i]=gi();
    69   for (RG int i=1;i<=n;++i)
    70     for (RG int j=1;j<=m;++j){
    71       RG char ch=gc();
    72       if (ch=='#') g[i][j]=-1; else g[i][j]=ch-'0';
    73       if (g[i][j]>=1 && g[i][j]<=9) p[g[i][j]]=(data){i,j};
    74     }
    75   for (RG int i=1;i<=n;++i)
    76     for (RG int j=1;j<=m;++j) if (!g[i][j]) spfa(i,j);
    77   cout<<ans; return 0;
    78 }
  • 相关阅读:
    Java开源框架推荐(全)
    Java性能提示(全)
    国外程序员整理的 C++ 资源大全 (zt)
    技术杂记之:在阿里云centos7上部署JDK MYSQL TOMCAT
    技术杂记之:vi使用入门
    Java全栈程序员之09:IDEA+GitHub
    SpringCloud无废话入门05:Spring Cloud Gateway路由、filter、熔断
    SpringCloud无废话入门04:Hystrix熔断器及监控
    SpringCloud无废话入门03:Feign声明式服务调用
    SpringCloud无废话入门02:Ribbon负载均衡
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7663677.html
Copyright © 2011-2022 走看看