zoukankan      html  css  js  c++  java
  • bzoj2755【SCOI2012】喵星人的入侵

    输入格式

    第一行为三个整数n,m,K,分别表示地图的长和宽,以及最多能放置的炮塔数量。 
    接下来的n行,每行包含m个字符,‘#’表示地图上原有的障碍,‘.’表示该处为空地,
    数据保证在原地图上存在S到T的路径。 


    输出格式

    输出在合理布阵下,喵星人采取最优策略后,会受到的最大伤害。 
    注意必须保证在布阵结束后喵星人仍然可以沿一条或以上的路径从起点S到达终点T,
    否则他们组织更大规模的侵略。 


    提示

    【数据范围】 
    对于30%的数据,保证:
    1<=N,M<=6
    对于100%的数据,保证:
    1<=N<=6,1<=M<=20,1<=K<=15,且从S到T的路径必定存在。


    • 题解:

      • 由于可以无限放置障碍,所以最后一定只会有一条路径;
      • 插头$dp$求出路径即可;
      • 注意和普通路径不同,路径不能组成四连通块;
      1 #include<bits/stdc++.h>
      2 #define il inline 
      3 #define rg register 
      4 using namespace std;
      5 const int N=10,M=21,sz=1e5;
      6 int n,m,K,c1[N],c2[N],cur,ans;
      7 char s[M][M];
      8 struct HASH{
      9     int o,hd[sz],v[sz],w[sz],nt[sz];
     10     il void init(){for(int i=1;i<=o;++i)hd[v[i]%sz]=0,v[i]=w[i]=nt[i]=0;o=0;}
     11     il void upd(int x,int y){
     12         for(rg int i=hd[x%sz];i;i=nt[i])if(v[i]==x){
     13             if(w[i]<y)w[i]=y;
     14             return;
     15         }
     16         nt[++o]=hd[x%sz],hd[x%sz]=o,v[o]=x,w[o]=y;
     17     }
     18 }f[2][M];
     19 il void upd(int&x,int y){if(x<y)x=y;}
     20 il void decode(int x){
     21     for(rg int i=0;i<=m;++i)c1[i]=x&3,x>>=2;
     22     for(rg int i=0;i<=m;++i)c2[i]=x&3,x>>=2;
     23 }
     24 il int encode(){
     25     int x=0;
     26     for(rg int i=m;~i;--i)x=(x<<2)^c2[i];
     27     for(rg int i=m;~i;--i)x=(x<<2)^c1[i];
     28     return x;
     29 }
     30 il int le(int x){
     31     for(rg int i=x,y=0;~i;--i)if(c1[i]&&c1[i]!=3){
     32         y+=(c1[i]&1)?1:-1;
     33         if(!y)return i;
     34     }return 0;
     35 }
     36 il int ri(int x){
     37     for(rg int i=x,y=0;i<=m;++i)if(c1[i]&&c1[i]!=3){
     38         y+=(c1[i]&1)?1:-1;
     39         if(!y)return i;
     40     }return 0;
     41 }
     42 il int cal1(int x){
     43     int l=max(x-1,0),r=min(x+2,m),re=0;
     44     for(rg int i=l;i<=r;++i)if(c2[i]==1)re++;
     45     return re;
     46 }
     47 il int cal2(int x){
     48     int l=max(x-1,0),r=min(x+2,m),re=0;
     49     for(rg int i=l;i<=r;++i)if(c2[i]==2)re++;
     50     return re;
     51 }
     52 il bool check(int j){
     53     for(rg int i=0;i<=m;++i)if(i!=j&&i!=j+1&&c1[i])return false;
     54     return true;
     55 }
     56 int main(){
     57     #ifndef ONLINE_JUDGE
     58     freopen("C.in","r",stdin);
     59     freopen("C.out","w",stdout);
     60     #endif
     61     scanf("%d%d%d",&n,&m,&K);
     62     for(rg int i=0;i<n;++i)scanf("%s",s[i]);
     63     if(n<m){
     64         for(rg int i=0;i<n;++i)
     65         for(rg int j=i+1;j<m;++j){
     66             swap(s[i][j],s[j][i]);
     67         }
     68         swap(n,m);
     69     }
     70     f[cur=0][0].upd(0,0);
     71     for(rg int i=0;i<n;++i)
     72     for(rg int j=0;j<m;++j){
     73         for(rg int k=0;k<=K;++k){
     74             for(rg int l=1;l<=f[cur][k].o;++l){
     75                 int w=f[cur][k].w[l];
     76                 decode(f[cur][k].v[l]);
     77                 if(!j){
     78                     if(c1[m])continue;
     79                     for(rg int i=m;i;--i)c1[i]=c1[i-1],c2[i]=c2[i-1];
     80                     c1[0]=c2[0]=0;
     81                 }
     82                 /*
     83                 { 
     84                     printf("%d %d %d:
    ",i,j,k);
     85                     for(int i=0;i<=m;++i)printf("%d ",c1[i]);
     86                     puts("");
     87                     for(int i=0;i<=m;++i)printf("%d ",c2[i]);
     88                     puts("");
     89                     printf("%d
    ",w);
     90                     printf("#
    ");
     91                 }*/
     92                 
     93                 int &p=c1[j],&q=c1[j+1],&r=c2[j],w1=w+cal1(j),w2=w+cal2(j);
     94                 int t1=j&&(c2[j-1]&1),t2=j!=m&&(c2[j+1]&1);
     95                 if(s[i][j]=='#'){
     96                     if(p||q)continue;
     97                     r=0,f[cur^1][k].upd(encode(),w);
     98                 }else if(!p&&!q){
     99                     if(s[i][j]=='.'){
    100                         p=0,q=0;
    101                         r=0,f[cur^1][k].upd(encode(),w);
    102                         if(k<K)r=2,f[cur^1][k+1].upd(encode(),w1);
    103                     }
    104                     if(t1||t2)continue;
    105                     if(s[i][j]=='S'||s[i][j]=='T'){
    106                         p=3,q=0,r=1,f[cur^1][k].upd(encode(),w2);
    107                         p=0,q=3,r=1,f[cur^1][k].upd(encode(),w2);
    108                     }else p=1,q=2,r=1,f[cur^1][k].upd(encode(),w2);
    109                 }else if(!p||!q){
    110                     if(t1&&t2)continue;
    111                     if(s[i][j]=='S'||s[i][j]=='T'){
    112                         if(p+q!=3){
    113                             if(p+q==1)c1[ri(j)]=3;else c1[le(j+1)]=3;
    114                             p=q=0,r=1,f[cur^1][k].upd(encode(),w2);
    115                         }
    116                         else if(check(j))p=0,q=0,r=1,f[cur^1][k].upd(encode(),w2);
    117                     }else{
    118                         r=1,swap(p,q),f[cur^1][k].upd(encode(),w2);
    119                         r=1,swap(p,q),f[cur^1][k].upd(encode(),w2);
    120                     }
    121                 }else{
    122                     if(p==3&&q==3){
    123                         p=q=0,r=1,f[cur^1][k].upd(encode(),w2);
    124                     }else if(p==3||q==3){
    125                         if(p+q-3==1)c1[ri(j)]=3;
    126                         else if(p+q-3==2)c1[le(j+1)]=3;
    127                         p=q=0,r=1,f[cur^1][k].upd(encode(),w2);
    128                     }else {
    129                         if(p==1&&q==2)continue;
    130                         if(p==q){
    131                             if(p==1)c1[ri(j+1)]=1;
    132                             else c1[le(j)]=2;
    133                         }
    134                         p=q=0,r=1,f[cur^1][k].upd(encode(),w2);
    135                     }
    136                 }
    137             }
    138             f[cur][k].init();
    139         }
    140         cur^=1;    
    141     }
    142     for(int i=1;i<=K;++i)
    143     for(int j=1;j<=f[cur][i].o;++j){
    144         decode(f[cur][i].v[j]);
    145         if(check(m+1))upd(ans,f[cur][i].w[j]);
    146     }
    147     printf("%d
    ",ans);
    148     return 0;
    149 }
    View Code
  • 相关阅读:
    三范式
    作用域
    函数传参
    js数据类型
    纯css小图标
    js生成div
    js模拟微信聊天窗口
    js图片切换
    js this指向
    常用实体字符
  • 原文地址:https://www.cnblogs.com/Paul-Guderian/p/10433605.html
Copyright © 2011-2022 走看看