• 【BZOJ】1187: [HNOI2007]神奇游乐园


    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1187


    每个格子都具有权值,求任意一个回路使得路径上的权值和最大。

    裸的插头DP,注意一下几点:

    1.因为不一定要全部格子都要走过,所以可以空一格不走,前提这个状态是没有上插头和左插头的。

    2.每个格子都应该可以作为起始状态(新建连通块)。

    3.关于形成回路的状态显然不能再往下转移,同时如果这个的轮廓线上除了左插头和右插头之外没有插头了,可以算入答案。

    QwQ...细节还是看代码吧。


      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<vector>
      5 #include<cstdlib>
      6 #include<cmath>
      7 #include<cstring>
      8 using namespace std;
      9 #define maxn 10010
     10 #define llg long long 
     11 #define sizee 57
     12 #define maxZT (1<<18)
     13 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
     14 llg n,m,now,size[2],zt[2][maxZT],ans,la,code[maxn],quan;
     15 llg v[2][maxZT];
     16 
     17 struct node
     18 {
     19     llg x,val,pos;
     20 };
     21 
     22 vector<node>a[2][sizee];
     23 
     24 void outcode(llg x) {for (llg i=0;i<=m;i++) code[i]=x&3,x>>=2;}
     25 
     26 void encode(llg p,llg val)
     27 {
     28     llg x=0;
     29     for (llg i=0;i<=m;i++) x+=code[i]*(1<<(i*2));
     30     llg wz=x%sizee,E=a[p][wz].size();
     31     for (llg i=0;i<E;i++)
     32         if (a[p][wz][i].x==x)
     33         {
     34             a[p][wz][i].val=max(a[p][wz][i].val,val);
     35             v[p][a[p][wz][i].pos]=max(v[p][a[p][wz][i].pos],val);
     36             return ;
     37         }
     38     size[p]++;
     39     node NEW; NEW.x=x; NEW.val=val; NEW.pos=size[p];
     40     a[p][wz].push_back(NEW);
     41     zt[p][size[p]]=x; v[p][size[p]]=val;
     42 }
     43 
     44 void init_a(llg p){for (llg i=0;i<sizee;i++) a[p][i].clear(); size[p]=0;}
     45 
     46 void DP()
     47 {
     48     llg now=0;
     49     encode(0,0);
     50     for (llg i=1;i<=n;i++)
     51     {
     52         for (llg k=1;k<=size[now];k++) zt[now][k]*=4;
     53         for (llg j=1;j<=m;j++)
     54         {
     55             scanf("%lld",&quan);
     56             now^=1; la=now^1; size[now]=0; 
     57             init_a(now);
     58             for (llg k=1;k<=size[la];k++)
     59             {
     60                 outcode(zt[la][k]);
     61                 llg le=code[j-1],up=code[j],V=v[la][k];
     62                 
     63                 if (!le && !up) //空格
     64                 {
     65                     encode(now,V);
     66                 }
     67 //-------------------------------------------------------------------------------------
     68                 if (!le && !up)//没有插头,新建连通分量
     69                 {
     70                     if (j<m)
     71                     {
     72                         code[j-1]=1,code[j]=2;
     73                         encode(now,V+quan);
     74                     }
     75                     continue;
     76                 }
     77 //-------------------------------------------------------------------------------------
     78                 if (!le && up)//延续上插头
     79                 {
     80                     if (j<m) encode(now,V+quan);
     81                     code[j-1]=code[j]; code[j]=0;
     82                     encode(now,V+quan);
     83                     continue;
     84                 }
     85 //-------------------------------------------------------------------------------------
     86                 if (le && !up)//延续左插头
     87                 {
     88                     encode(now,V+quan);
     89                     if (j<m) 
     90                     {
     91                         code[j]=code[j-1]; code[j-1]=0;
     92                         encode(now,V+quan);
     93                     }
     94                     continue;
     95                 }
     96 //-------------------------------------------------------------------------------------
     97                 if (le==1 && up==2)//回路闭合,统计答案
     98                 {
     99                     bool pd=true;
    100                     for (llg e=0;e<j-1;e++) if (code[e]) pd=false;
    101                     for (llg e=j+1;e<=m;e++) if (code[e]) pd=false;
    102                     if (pd) ans=max(ans,V+quan);
    103                     //        if (pd) cout<<i<<" "<<j<<"--->"<<V+quan<<endl;
    104                     continue;
    105                 }
    106 //-------------------------------------------------------------------------------------
    107                 if (le==2 && up==1)//左插头为右括号,上插头为左括号,直接合并
    108                 {
    109                     code[j]=code[j-1]=0;
    110                     encode(now,V+quan);
    111                     continue;
    112                 }
    113 //-------------------------------------------------------------------------------------
    114                 if (le==1 && up==1)//上左插头均为左括号,找到上插头所对应的右括号并将其修改为左括号
    115                 {
    116                     for (llg e=j+1;e<=m;e++) 
    117                         if (code[e]==2)
    118                         {
    119                             code[e]=1;
    120                             break;
    121                         } 
    122                     code[j]=code[j-1]=0;
    123                     encode(now,V+quan);
    124                     continue;
    125                 }
    126 //-------------------------------------------------------------------------------------
    127                 if (le==2 && up==2)//上左插头均为右括号,找到左插头对应的左括号并将其修改为右括号
    128                 {
    129                     for (llg e=j-2;e>=0;e--)
    130                         if (code[e]==1)
    131                         {
    132                             code[e]=2;
    133                             break;
    134                         }
    135                     code[j]=code[j-1]=0;
    136                     encode(now,V+quan);
    137                     continue;
    138                 }
    139             }
    140         }
    141     }
    142 }
    143 
    144 int main()
    145 {
    146     yyj("a");
    147     ans=-1*0x7fffffff;
    148     cin>>n>>m;
    149     DP();
    150     cout<<ans;
    151     return 0;
    152 }
    本文作者:xrdog 作者博客:http://www.cnblogs.com/Dragon-Light/ 转载请注明出处,侵权必究,保留最终解释权!
  • 相关阅读:
    UVa 1374
    天梯赛L3 004
    redis操作ZSet
    redis操作set集合
    mybatis使用注解开发
    SSM整合之mybatis的别名配置
    mybatis的5.1.10分页插件的使用
    lombok的使用
    JDBC的一个简单工具类
    mybatis的测试
  • 原文地址:https://www.cnblogs.com/Dragon-Light/p/6426438.html
Copyright © 2020-2023  润新知