zoukankan      html  css  js  c++  java
  • [BZOJ1294][SCOI2009]围豆豆Bean 射线法+状压dp+spfa

    1294: [SCOI2009]围豆豆Bean

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 458  Solved: 305
    [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

    HINT

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

    从每个豆豆射出一条射线,若经过路线奇数次则说明路线将其包围,若经过偶数次则不包围。

    设状态f[i][j][k]表示到达(i,j)围豆豆状态为k的最大价值。

    每次枚举起点,用spfa转移即可。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #define maxn 15
     8 using namespace std;
     9 int tx[5]={1,-1,0,0};
    10 int ty[5]={0,0,1,-1};
    11 char a[maxn];
    12 int num[maxn][maxn];
    13 int val[maxn];
    14 int n,m,d;
    15 int x[maxn],y[maxn];
    16 int f[maxn][maxn][600];
    17 int inq[maxn][maxn][600];
    18 int ans=0;
    19 struct data {
    20     int x,y,z;
    21 }q[10000];
    22 void work(int i,int j) {
    23     memset(f,-97,sizeof(f));
    24     int head=0,tail=1;
    25     q[0]=(data){i,j,0};
    26     f[i][j][0]=0;
    27     while(head!=tail) {
    28         data now=q[head++];if(head==9000) head=0;
    29         if(now.x==i&&now.y==j) ans=max(ans,f[now.x][now.y][now.z]);
    30         for(int k=0;k<4;k++) {
    31             int tox=now.x+tx[k],toy=now.y+ty[k],toz=now.z;
    32             int add=0;
    33             if(tox<1||toy<1||tox>n||toy>m||num[tox][toy]!=0) continue;
    34             if(now.x!=tox) {
    35                 data temp;
    36                 if(tox>now.x) temp=(data){now.x,now.y,now.z};else temp=(data){tox,toy,now.z};
    37                 for(int l=1;l<=d;l++) {
    38                     if(temp.y>y[l]&&temp.x==x[l]) {
    39                         temp.z^=(1<<(l-1));
    40                         if(temp.z&(1<<(l-1))) add+=val[l];
    41                         else add-=val[l];
    42                     }
    43                 }
    44                 toz=temp.z;
    45             }
    46             if(f[tox][toy][toz]<f[now.x][now.y][now.z]+add-1){
    47                 f[tox][toy][toz]=f[now.x][now.y][now.z]+add-1;
    48                 if(!inq[tox][toy][toz]) {
    49                     q[tail++]=(data){tox,toy,toz};if(tail==9000) tail=0;
    50                     inq[tox][toy][toz]=1;
    51                 }
    52             }
    53             inq[now.x][now.y][now.z]=0;
    54         }
    55     }
    56 }
    57 int main() {
    58     scanf("%d%d%d",&n,&m,&d);
    59     for(int i=1;i<=d;i++) scanf("%d",&val[i]);
    60     for(int i=1;i<=n;i++) {
    61         scanf("%s",a+1);
    62         for(int j=1;j<=m;j++) {
    63             if(a[j]=='0') num[i][j]=0;
    64             else if(a[j]!='#') x[a[j]-'0']=i,y[a[j]-'0']=j,num[i][j]=-1;
    65             else num[i][j]=1;
    66         }
    67     }
    68     for(int i=1;i<=n;i++)
    69         for(int j=1;j<=m;j++)
    70             if(num[i][j]==0) work(i,j);
    71     printf("%d",ans);
    72     return 0;
    73 }
    View Code
    O(∩_∩)O~ (*^__^*) 嘻嘻…… O(∩_∩)O哈哈~
  • 相关阅读:
    nodejs向远程服务器发送post请求----融云Web SDK/客户端获取token
    Oauth2.0认证---授权码模式
    AngularJS---自定义指令
    Leetcode160-Intersection of Two Linked Lists-Easy
    Lintcode489-Convert Array List to Linked List-Easy
    Lintcode228-Middle of Linked List-Naive
    Lintcode174-Remove Nth Node From End of List-Easy
    Lintcode225-Find Node in Linked List-Naive
    Lintcode85-Insert Node in a Binary Search Tree-Easy
    Lintcode93-Balanced Binary Tree-Easy
  • 原文地址:https://www.cnblogs.com/wls001/p/7717883.html
Copyright © 2011-2022 走看看