luogu 1006 传纸条
Posted asdic
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu 1006 传纸条相关的知识,希望对你有一定的参考价值。
三/四维dp,将两次传递均看作从左上而来,在dp过程中注意防止越界/重合
f[i][j][k][l]直接枚举两轮的点,如下
#include<bits/stdc++.h> #define rep(i,x,y) for(register int i=x;i<=y;i++) const int N=55; using namespace std; int f[N][N][N][N],mp[N][N],m,n; int MAX(int a,int b,int c,int d){ int m1=max(a,b),m2=max(c,d); int m3=max(m1,m2); if(m3==a) return a; if(m3==b) return b; if(m3==c) return c; if(m3==d) return d; } int main(){ scanf("%d%d",&m,&n); rep(i,1,m)rep(j,1,n) scanf("%d",&mp[i][j]); rep(i,1,m)rep(j,1,n)rep(k,1,m)rep(l,j+1,n) f[i][j][k][l]=mp[i][j]+mp[k][l]+MAX(f[i][j-1][k][l-1],f[i][j-1][k-1][l],f[i-1][j][k][l-1],f[i-1][j][k-1][l]); printf("%d ",f[m][n-1][m-1][n]); return 0; }
但空间时间并不优秀,利用i+j=k+l=step的特性减少一维,分别只枚举i.k再计算另一维即可
#include<bits/stdc++.h> #define rep(i,x,y) for(register int i=x;i<=y;i++) const int N=55; using namespace std; int f[N<<1][N][N],mp[N][N],m,n; int MAX(int a,int b,int c,int d){ int m1=max(a,b),m2=max(c,d); int m3=max(m1,m2); if(m3==a) return a; if(m3==b) return b; if(m3==c) return c; if(m3==d) return d; } int main(){ scanf("%d%d",&m,&n); rep(i,1,m)rep(j,1,n) scanf("%d",&mp[i][j]); rep(k,1,m+n-1)rep(i,1,m)rep(j,1,m){ if(k-i<0||k-j<0) continue; f[k][i][j]=mp[i][k-i+1]+mp[j][k-j+1]+MAX(f[k-1][i][j],f[k-1][i][j-1],f[k-1][i-1][j],f[k-1][i-1][j-1]); if(i==j) f[k][i][j]-=mp[i][k-i+1]; }printf("%d ",f[m+n-1][n][n]); return 0; }
还有滚动数组可以降至二维,但不会写...emmm
以上是关于luogu 1006 传纸条的主要内容,如果未能解决你的问题,请参考以下文章