BZOJ 1187 HNOI2007 神奇游乐园 插头DP
2015-09-15 19:56
393 查看
题目大意:给定一个四联通的网格图,每个点有个权值,求一个长度至少为4的简单环使得环上权值和最大
插头DP,具体自己讨论吧这题没啥可说的
注意(1,2)−>(0,0)(1,2)->(0,0)的状态要转移到答案上而不能转移到DP数组里
插头DP,具体自己讨论吧这题没啥可说的
注意(1,2)−>(0,0)(1,2)->(0,0)的状态要转移到答案上而不能转移到DP数组里
[code]#include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; int n,m,ans=0xefefefef; int a[101][7],f[102][7][1<<14]; vector<pair<int,bool> > trans[7][1<<14]; int Impress(int a[]) { int i,re=0; for(i=0;i<=m;i++) re|=a[i]<<i*2; return re; } void Calculate(int sta) { static int a[10],b[10],another[10],stack[10]; int i,top=0; for(i=0;i<=m;i++) a[i]=(sta>>i*2)&3; for(i=0;i<=m;i++) { if(a[i]==0) continue; if(a[i]==3) return ; if(a[i]==1) stack[++top]=i; else { if(top==0) return ; another[stack[top]]=i; another[i]=stack[top]; stack[top--]=0; } } if(top) return ; for(i=1;i<=m;i++) { switch(a[i-1]<<2|a[i]) { case 0<<2|0: { memcpy(b,a,sizeof b); trans[i][sta].push_back(pair<int,bool>(Impress(b),false)); b[i-1]=1;b[i]=2; trans[i][sta].push_back(pair<int,bool>(Impress(b),true)); break; } case 0<<2|1: { memcpy(b,a,sizeof b); trans[i][sta].push_back(pair<int,bool>(Impress(b),true)); b[i-1]=1;b[i]=0; trans[i][sta].push_back(pair<int,bool>(Impress(b),true)); break; } case 0<<2|2: { memcpy(b,a,sizeof b); trans[i][sta].push_back(pair<int,bool>(Impress(b),true)); b[i-1]=2;b[i]=0; trans[i][sta].push_back(pair<int,bool>(Impress(b),true)); break; } case 1<<2|0: { memcpy(b,a,sizeof b); trans[i][sta].push_back(pair<int,bool>(Impress(b),true)); b[i-1]=0;b[i]=1; trans[i][sta].push_back(pair<int,bool>(Impress(b),true)); break; } case 1<<2|1: { memcpy(b,a,sizeof b); b[i-1]=b[i]=0;b[another[i]]=1; trans[i][sta].push_back(pair<int,bool>(Impress(b),true)); break; } case 1<<2|2: { memcpy(b,a,sizeof b); b[i-1]=b[i]=0; if( Impress(b)==0 ) trans[i][sta].push_back(pair<int,bool>(-1,true)); break; } case 2<<2|0: { memcpy(b,a,sizeof b); trans[i][sta].push_back(pair<int,bool>(Impress(b),true)); b[i-1]=0;b[i]=2; trans[i][sta].push_back(pair<int,bool>(Impress(b),true)); break; } case 2<<2|1: { memcpy(b,a,sizeof b); b[i-1]=b[i]=0; trans[i][sta].push_back(pair<int,bool>(Impress(b),true)); break; } case 2<<2|2: { memcpy(b,a,sizeof b); b[i-1]=b[i]=0;b[another[i-1]]=2; trans[i][sta].push_back(pair<int,bool>(Impress(b),true)); break; } } } } int main() { vector<pair<int,bool> >::iterator it; int i,j,k; cin>>n>>m; for(i=1;i<=n;i++) for(j=1;j<=m;j++) scanf("%d",&a[i][j]); for(k=0;k<1<<(m+1<<1);k++) Calculate(k); memset(f,0xef,sizeof f); f[1][0][0]=0; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) for(k=0;k<1<<(m+1<<1);k++) for(it=trans[j][k].begin();it!=trans[j][k].end();it++) { if(i==1&&j==2&&k==9) ++i,--i; int &val=it->first!=-1?f[i][j][it->first]:ans; val=max(val,f[i][j-1][k]+it->second*a[i][j]); } for(k=0;k<1<<(m<<1);k++) f[i+1][0][k<<2]=f[i][m][k]; } cout<<ans<<endl; return 0; }
相关文章推荐
- HDOJ 5432 Pyramid Split(二分)
- 移动开发之fastclick 点击穿透
- LeetCode_best-time-to-buy-and-sell-stock
- iOS程序启动的完整过程
- 植物大战僵尸无限版轮数地址
- HTML 标题、水平线、注释、查看网页源码
- javascript中的function
- Python简明教程---学习笔记
- HDOJ 2609How many
- JSP第一次运行tomcat7.0的404错误
- 跟马哥学linux (lesson 7)Bash脚本基础知识
- MongoDB学习日记 - java代码(二):建立连接
- hdu1018(求n!的位数)
- SQL学习记录
- SoundPool提示音铃声
- Linux 下的yum的配置
- OC - NSString
- Serializable序列化与session
- 获得桌面图标所在窗口--兼容Win7
- Android程序启动画面之Splash