• [HNOI2007][bzoj1187] 神奇游乐园 [插头dp]


    题面:

    传送门

    给定一个四联通棋盘图,每个格子有权值,求一条总权值最大的回路

    思路:

    插头dp基础教程

    棋盘?

    回路?

    n,m<=10?

    当然是插头dp啦~(≧▽≦)/~

    然后发现这道题并不是哈密顿回路了......需要考虑一下终止条件的不同,对比URAL1519

    诚然,回路问题中依然可以用括号表示法来压缩状态,但是此时形成回路、统计答案的就不仅仅在最后一个非障碍格子才可以,而是任何时候,只要状态中只剩下一对左右插头满足条件(看不懂这里的可以去上面那道题看看)

    同时请注意,这道题统计的是最值、不是和值

    同时请注意,这题可能会爆longlong......我丧病地开了__int128,避免了高精度的地狱

    Code:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define ll long long
      6 #define hash deep_dark_fantasy
      7 #define inf 1e9
      8 using namespace std;
      9 inline int read(){
     10     int re=0,flag=1;char ch=getchar();
     11     while(ch>'9'||ch<'0'){
     12         if(ch=='-') flag=-1;
     13         ch=getchar();
     14     }
     15     while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
     16     return re*flag;
     17 }
     18 int n,m,x[150][150],cur,pre,ex,ey;
     19 int st[2][300010];ll ans[2][300010],re;
     20 int tot[2],bit[20],state[300010],st_tot,hash=300000;
     21 struct edge{
     22     int to,next;
     23 }a[300010];
     24 void insert(int sta,ll val){
     25     int p=sta%hash,i;
     26     for(i=state[p];i;i=a[i].next){
     27         if(st[cur][a[i].to]==sta){
     28             ans[cur][a[i].to]=max(ans[cur][a[i].to],val);return;
     29         }
     30     }
     31     tot[cur]++;
     32     a[++st_tot].to=tot[cur];
     33     a[st_tot].next=state[p];
     34     state[p]=st_tot;st[cur][tot[cur]]=sta;ans[cur][tot[cur]]=val;
     35 }
     36 void dp(){
     37     int i,j,k,l,now,down,right;ll val;re=-inf;
     38     cur=0;tot[cur]=1;ans[cur][1]=0;st[cur][1]=0;
     39     for(i=1;i<=n;i++){
     40         for(j=1;j<=tot[cur];j++) st[cur][j]<<=2;
     41         for(j=1;j<=m;j++){
     42             pre=cur;cur^=1;tot[cur]=0;st_tot=0;memset(state,0,sizeof(state));
     43             for(k=1;k<=tot[pre];k++){
     44                 now=st[pre][k];val=ans[pre][k];
     45                 right=(now>>bit[j-1])%4;down=(now>>bit[j])%4;
     46                 if(!down&&!right){
     47                     insert(now,val);
     48                     if(j!=m) 
     49                         insert(now+(1<<bit[j-1])+((1<<bit[j])<<1),val+x[i][j]);
     50                 }
     51                 if(down&&!right){
     52                     insert(now-down*(1<<bit[j])+down*(1<<bit[j-1]),val+x[i][j]);
     53                     if(j!=m)insert(now,val+x[i][j]);
     54                 }
     55                 if(right&&!down){
     56                     insert(now,val+x[i][j]);
     57                     if(j!=m) 
     58                         insert(now+right*(1<<bit[j])-right*(1<<bit[j-1]),val+x[i][j]);
     59                 }
     60                 if(right==1&&down==1){
     61                     int cnt=1;
     62                     for(l=j+1;l<=m;l++){
     63                         if((now>>bit[l])%4==1) cnt++;
     64                         if((now>>bit[l])%4==2) cnt--;
     65                         if(!cnt){
     66                             insert(now-(1<<bit[l])-(1<<bit[j])-(1<<bit[j-1]),val+x[i][j]);
     67                             break;
     68                         }
     69                     }
     70                 }
     71                 if(right==2&&down==2){
     72                     int cnt=1;
     73                     for(l=j-2;l>=0;l--){
     74                         if((now>>bit[l])%4==1) cnt--;
     75                         if((now>>bit[l])%4==2) cnt++;
     76                         if(!cnt){
     77                             insert(now+(1<<bit[l])-((1<<bit[j])<<1)-((1<<bit[j-1])<<1),val+x[i][j]);
     78                             break;
     79                         }
     80                     }
     81                 }
     82                 if(right==2&&down==1){
     83                     insert(now-((1<<bit[j-1])<<1)-(1<<bit[j]),val+x[i][j]);
     84                 }
     85                 if(right==1&&down==2){
     86                     if((now==(1<<bit[j-1])+((1<<bit[j])<<1))&&(val+x[i][j]>re)){
     87                         re=val+x[i][j];
     88                     }
     89                 }
     90             }
     91         }
     92     }
     93 }
     94 int main(){
     95     int i,j;
     96     n=read();m=read();
     97     for(i=1;i<=10;i++) bit[i]=(i<<1);
     98     for(i=1;i<=n;i++) for(j=1;j<=m;j++) x[i][j]=read();
     99     dp();
    100     printf("%lld",re);
    101 }
  • 相关阅读:
    【转】Chrome 控制台不完全指南
    AngularJS 之 Factory vs Service vs Provider【转】
    【转】NuGet.org 无法访问的解决方法
    jquery easyui 1.4.1 验证时tooltip 的位置调整
    jquery easyui 1.4.1 API( CHM版)
    扩展 easyui-tabs 插件 关闭标签页方法
    easyui layout 折叠后显示标题
    easyui 中Datagrid 控件在列较多且无数据时,列显示不全的解决方案
    为easyui datagrid 添加上下方向键移动
    Android布局实现圆角边框
  • 原文地址:https://www.cnblogs.com/dedicatus545/p/8629572.html
Copyright © 2020-2023  润新知