hdu 3377 Plan
来源:互联网 发布:个人域名有什么用 编辑:程序博客网 时间:2024/06/06 15:41
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3377
题目大意:求一条简单路径的最大值。
题目思路:可转化为单回路来做,不过因为不是每个点都要选,所以在没有左插头和右插头的情况下可以不加插头。
#include<stdio.h>#include<string.h>#define Max 1001000#define inf 0x3f3f3f3f#define Hash 3007int n,m,ex,ey,cur,mp[15][15],a1,a2,a3,b1,b2,b3,count;int stack[15],f[15];char str[15];inline int max(int a,int b){ return a>b?a:b;}struct node{ int size,next[Max],p[Hash],state[Max]; int f[Max]; inline void init() { memset(p,-1,sizeof(p)); size=0; } inline void push(int st,int val) { int i,u=st%Hash; for(i=p[u];i!=-1;i=next[i]) { if(state[i]==st) { f[i]=max(f[i],val); return; } } state[size]=st;f[size]=val; next[size]=p[u]; p[u]=size++; }}dp[2];inline void decode(int st){ int top=0; for(int i=0;i<=m;i++) { if((st&3)==1) stack[top++]=i; else if((st&3)==2) { f[stack[top-1]]=i; f[i]=stack[top-1]; top--; } st>>=2; }}inline void shift(){ for(int k=0;k<dp[cur].size;k++) dp[cur^1].push(dp[cur].state[k]<<2,dp[cur].f[k]);}inline void dpblank(int i,int j){ int k,left,up; // printf("i %d j %d size %d\n",i,j,dp[cur].size); for(k=0;k<dp[cur].size;k++) { int st=dp[cur].state[k]; left=st&a3; up=st&b3; if(left&&up) { if(left==a1&&up==b2) { if(i==ex&&j==ey) dp[cur^1].push(st^left^up,dp[cur].f[k]+mp[i][j]); } else { if(left==a2&&up==b1) dp[cur^1].push(st^left^up,dp[cur].f[k]+mp[i][j]); if(left==a1&&up==b1) { decode(st); dp[cur^1].push(st^left^up^(3<<(2*f[j])),dp[cur].f[k]+mp[i][j]); } if(left==a2&&up==b2) { decode(st); dp[cur^1].push(st^left^up^(3<<(2*f[j-1])),dp[cur].f[k]+mp[i][j]); } } } else if(left) { if(mp[i][j+1]!=-inf) dp[cur^1].push((st^left)|(left<<2),dp[cur].f[k]+mp[i][j]); if(mp[i+1][j]!=-inf) dp[cur^1].push(st,dp[cur].f[k]+mp[i][j]); } else if(up) { if(mp[i][j+1]!=-inf) dp[cur^1].push(st,dp[cur].f[k]+mp[i][j]); if(mp[i+1][j]!=-inf) dp[cur^1].push((st^up)|(up>>2),dp[cur].f[k]+mp[i][j]); } else { if(mp[i][j+1]!=-inf&&mp[i+1][j]!=-inf) dp[cur^1].push(st|a1|b2,dp[cur].f[k]+mp[i][j]); if(i!=ex||j!=ey) dp[cur^1].push(st,dp[cur].f[k]); } }}inline void solve(){ int i,j,k; int ans=-inf; cur=0; dp[0].init(); dp[0].push(0,0); for(i=1;i<=n;i++) { dp[cur^1].init(); shift(); cur^=1; b1=1;b2=2; for(j=1;j<=m;j++) { a1=b1;a2=b2;a3=a1|a2; b1<<=2;b2<<=2;b3=b1|b2; if(mp[i][j]!=-inf) { dp[cur^1].init(); dpblank(i,j); cur^=1; } } } for(k=0;k<dp[cur].size;k++) ans=max(dp[cur].f[k],ans); printf("Case %d: %d\n",count++,ans);}int main(){ int i,j; count=1; while(scanf("%d%d",&n,&m)!=EOF) { ex=0; for(i=0;i<15;i++) for(j=0;j<15;j++) mp[i][j]=-inf; for(i=1;i<=m+2;i++) mp[1][i]=0; for(i=3;i<=n+2;i++) { for(j=1;j<=m;j++) { scanf("%d",&mp[i][j]); } mp[i][m+2]=0; } mp[2][1]=mp[n+2][m+1]=mp[2][m+2]=0; n+=2;m+=2; ex=n;ey=m; solve(); } return 0;}
- hdu 3377 Plan
- hdu 3377 Plan
- HDU 3377 Plan
- HDU 3377 Plan
- hdu 3377 Plan(插头dp)
- hdu 3377 Plan 插头dp
- HDU 2103 Family Plan
- hdu 3757 Evacuation Plan
- HDU 4671 Backup Plan
- hdu-4671 Backup Plan
- HDU 4671 Backup Plan
- HDU 3757 Evacuation Plan
- Secrete Master Plan HDU
- HDU-3757-Evacuation Plan
- HDU 3377 Plan 解题报告(插头DP)
- HDU 4671 Backup Plan (水题)
- hdu 4671 Backup Plan 构造
- hdu 1964 Plan (插头dp)
- Java集合HashSet中的两个对象怎样算重复
- 线程池相关链接
- agetty
- C++多线程(一)
- 无处着手
- hdu 3377 Plan
- UVA 试题 537
- mapreduce源码分析之TaskTracker的启动
- C++多线程(二)
- TouchSliderBox 1.0 –容器宽度可变的幻灯
- mapreduce源码分析之HeartBeat机制
- android TabHost小结
- 文件收藏
- open jquery