zoj 3213 Beautiful Meadow 插头dp
2012-10-07 19:00
302 查看
求任意路径可以得到的最大权值和,这题和前面的题目不一样,插头的起点和结束点都不是确定的,所以要加一个插头表示单插头,表示起点或终点,接着就是恶心的转移,一直漏一个条件,后来看小hh的代码发现问题,终于过了。
Run ID | Submit Time | Judge Status | Problem ID | Language | Run Time(ms) | Run Memory(KB) | User Name |
3077610 | 2012-10-07 01:06:32 | Accepted | 3213 | C++ | 150 | 1596 | xym |
#include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<iostream> #define LL long long using namespace std; const int maxn=30001,INF=1<<30; int mov[10]={0,2,4,6,8,10,12,14,16,18}; struct node { int size,head[maxn],next[maxn]; LL sta[maxn],sum[maxn]; void clear() { memset(head,-1,sizeof(head)); size=0; } void push(LL st,const LL v) { LL hash=st%maxn; for(int i=head[hash];i>=0;i=next[i]) { if(sta[i]==st) { sum[i]=max(sum[i],v); return ; } } sta[size]=st,sum[size]=v; next[size]=head[hash],head[hash]=size++; } }dp[2]; inline int getbit(LL st,int k){return 3&(st>>mov[k]);} inline int pybit(LL st,int k){return st<<mov[k];} inline int clrbit(LL st,int a,int b){return st&(~(3<<mov[a]))&(~(3<<mov[b]));} int fl(LL st,int k,int m) { int cnt=1; for(int i=k+1;i<=m;i++) { int e=getbit(st,i); if(e==2) cnt--; else if(e==1) cnt++; if(!cnt) return i; } } int fr(LL st,int k) { int cnt=1; for(int i=k-1;i>=0;i--) { int e=getbit(st,i); if(e==2) cnt++; else if(e==1) cnt--; if(!cnt) return i; } } int count(LL st) { int cnt=0; while(st) { if(getbit(st,0)==3) cnt++; st>>=2; } return cnt; } int n,m,gp[20][20]; LL DP() { LL ans=-INF; dp[0].clear(); dp[0].push(0,0); int now=0,pre=1; for(int i=1;i<=n;i++) { pre=now,now^=1,dp[now].clear(); for(int j=0;j<dp[pre].size;j++) dp[now].push(dp[pre].sta[j]<<2,dp[pre].sum[j]); for(int j=1;j<=m;j++) { if(gp[i][j]!=0) ans=max(ans,(LL)gp[i][j]); pre=now,now^=1,dp[now].clear(); for(int k=0;k<dp[pre].size;k++) { LL l=getbit(dp[pre].sta[k],j-1); LL up=getbit(dp[pre].sta[k],j); LL st=clrbit(dp[pre].sta[k],j,j-1); LL v=dp[pre].sum[k]+gp[i][j]; //cout<<i<<' '<<j<<' '<<l<<' '<<up<<' '<<st<<' '<<v<<endl; if(!l&&!up) { dp[now].push(st,dp[pre].sum[k]); if(gp[i][j]==0) continue; if(i<n&&j<m&&gp[i+1][j]&&gp[i][j+1]) dp[now].push(st|pybit(1,j-1)|pybit(2,j),v); if(count(st)<=1) { if(i<n&&gp[i+1][j]) dp[now].push(st|pybit(3,j-1),v); if(j<m&&gp[i][j+1]) dp[now].push(st|pybit(3,j),v); } } else if(!l||!up) { int e=l+up; if(i<n&&gp[i+1][j]) dp[now].push(st|pybit(e,j-1),v); if(j<m&&gp[i][j+1]) dp[now].push(st|pybit(e,j),v); if(e!=3&&count(st)<=1) { if(e==1) dp[now].push(st|pybit(3,fl(st,j,m)),v); else dp[now].push(st|pybit(3,fr(st,j-1)),v); } else if(e==3&&st==0) ans=max(ans,v); } else if(l==up) { if(l==1) dp[now].push(st^pybit(3,fl(st,j,m)),v); if(l==2) dp[now].push(st^pybit(3,fr(st,j-1)),v); if(l==3) ans=max(ans,v); } else if(l==2&&j==1) dp[now].push(st,v); else if(l==3||up==3) { int e=l==3?up:l; if(e==1) dp[now].push(st|pybit(3,fl(st,j,m)),v); if(e==2) dp[now].push(st|pybit(3,fr(st,j-1)),v); } } } } if(ans==-INF) ans=0; return ans; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&gp[i][j]); cout<<DP()<<endl; } return 0; }
相关文章推荐
- ZOJ 3213 Beautiful Meadow(插头DP-一条路径最大值,不固定头尾)
- zoj 3213(插头DP 一条路径)
- ZOJ 3213 Beautiful Meadow(插头DP)
- ZOJ 3213 Beautiful Meadow 解题报告(插头DP)
- ZOJ 3466 The Hive II(插头DP)
- ZOJ 3466 The Hive II (插头DP,变形)
- ZOJ 3256 Tour in the Castle (插头DP求回路个数+矩阵乘法)
- ZOJ 3466 The Hive II 解题报告(插头DP)
- zoj 3213 Beautiful Meadow(插头dp)
- ZOJ 3466 The Hive II 插头DP
- ZOJ 3466 插头dp
- ZOJ 3256 Tour in the Castle(插头DP-按行递推—矩阵)
- ZOJ 3256 Tour in the Castle 解题报告(插头DP)
- zoj 3466 The Hive II(插头dp)
- zoj 3466(插头DP 多条回路 六边形)
- poj 2411(插头DP 简单题)
- ZOJ 1027 Human Gene Functions (DP)
- ZOJ 3735 Josephina and RPG (概率DP)
- zoj 3494 BCD Code (ac自动机+数位dp)
- ZOJ 1346 Comparing Your Heroes - 状压dp