CodeForces - 762D Maximum path (插头dp(广义括号法))
题意:一个3*n的带权矩阵,问从左上角走到右下角所经过路径的最大权值和
正解貌似是找规律+dp,不过显然可以插头dp直接搞,代码很长虽然满满的都是套路。。。
因为这题有起点和终点,也就意味着可能会出现单侧插头的情况,因此括号情况除了'','(',')'之外,还需要增加一种'()',转移的时候也需要多考虑几种情况
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=1e5+10,MXS=1000; 5 const ll inf=0x3f3f3f3f3f3f3f3fll; 6 int a[N][5],n,m,sx,sy,tx,ty; 7 struct Hashmap { 8 static const int N=MXS; 9 int hd[N],nxt[N],fa[N],tot; 10 int p[N]; 11 ll q[N]; 12 Hashmap() {memset(hd,-1,sizeof hd),tot=0;} 13 void clear() {for(int i=0; i<tot; ++i)hd[fa[i]]=-1; tot=0;} 14 ll& operator[](int x) { 15 int u=x%N; 16 for(int i=hd[u]; ~i; i=nxt[i])if(p[i]==x)return q[i]; 17 nxt[tot]=hd[u],fa[tot]=u,p[tot]=x,q[tot]=~inf,hd[u]=tot; 18 return q[tot++]; 19 } 20 int count(int x) { 21 int u=x%N; 22 for(int i=hd[u]; ~i; i=nxt[i])if(p[i]==x)return 1; 23 return 0; 24 } 25 } dp[2]; 26 int getl(int S,int j) {return S>>((j-1)<<1)&3;} 27 int getu(int S,int j) {return S>>(j<<1)&3;} 28 int trans(int S,int j,int d,int r) {return (S&~(15<<((j-1)<<1)))|(d<<((j-1)<<1))|(r<<(j<<1));} 29 int trans(int S,int j,int d) {return (S&~(3<<(j<<1)))|(d<<(j<<1));} 30 int find(int S,int j,int f) { 31 int d=(f==1?1:-1); 32 for(int k=j+d,c=1;; k+=d) { 33 if(getu(S,k)==f)++c; 34 else if(getu(S,k)==(f^3))--c; 35 if(c==0)return k; 36 } 37 return -1; 38 } 39 void upd(ll& t,ll x) {if(x>t)t=x;} 40 ll solve() { 41 upd(dp[0][0],0); 42 int f=0; 43 for(int i=1; i<=n; ++i) 44 for(int j=1; j<=m; ++j,f^=1) { 45 Hashmap &F=dp[f],&G=dp[f^1]; 46 G.clear(); 47 for(int k=0; k<F.tot; ++k) { 48 int S=F.p[k]; 49 ll g=F.q[k]; 50 if(j==1) {if(getl(S,m+1))continue; S<<=2;} 51 int l=getl(S,j),u=getu(S,j); 52 if((i==sx&&j==sy)||(i==tx&&j==ty)) { 53 if(!l&&!u)upd(G[trans(S,j,3,0)],g+a[i][j]),upd(G[trans(S,j,0,3)],g+a[i][j]); 54 else if((l==1||l==2)&&!u)upd(G[trans(trans(S,j,0,0),find(S,j-1,l),3)],g+a[i][j]); 55 else if(!l&&(u==1||u==2))upd(G[trans(trans(S,j,0,0),find(S,j,u),3)],g+a[i][j]); 56 else if((l==3&&!u)||(!l&&u==3))upd(G[trans(S,j,0,0)],g+a[i][j]); 57 } else { 58 if(!l&&!u)upd(G[S],g),upd(G[trans(S,j,1,2)],g+a[i][j]); 59 else if(!l&&u)upd(G[S],g+a[i][j]),upd(G[trans(S,j,u,0)],g+a[i][j]); 60 else if(l&&!u)upd(G[S],g+a[i][j]),upd(G[trans(S,j,0,l)],g+a[i][j]); 61 else if(l==1&&u==1)upd(G[trans(trans(S,j,0,0),find(S,j,1),1)],g+a[i][j]); 62 else if(l==2&&u==2)upd(G[trans(trans(S,j,0,0),find(S,j-1,2),2)],g+a[i][j]); 63 else if((l==2&&u==1)||(l==3&&u==3))upd(G[trans(S,j,0,0)],g+a[i][j]); 64 else if((l==1||l==2)&&u==3)upd(G[trans(trans(S,j,0,0),find(S,j-1,l),3)],g+a[i][j]); 65 else if(l==3&&(u==1||u==2))upd(G[trans(trans(S,j,0,0),find(S,j,u),3)],g+a[i][j]); 66 } 67 } 68 } 69 return dp[f][0]; 70 } 71 int main() { 72 scanf("%d",&n); 73 m=3; 74 sx=1,sy=3,tx=n,ty=1; 75 for(int j=m; j>=1; --j) 76 for(int i=1; i<=n; ++i) 77 scanf("%d",&a[i][j]); 78 printf("%lld\n",solve()); 79 return 0; 80 }
蛋疼的画解路径图的程序:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=10+10,M=14,MXS=1e4; 5 const ll inf=0x3f3f3f3f3f3f3f3fll; 6 int a[N][M],n,m,sx,sy,tx,ty; 7 struct D {int i,j,S;}; 8 template<class T1,class T2> 9 class Hashmap { 10 public: 11 static const int N=MXS; 12 int hd[N],nxt[N],fa[N],tot; 13 T1 p[N]; 14 T2 q[N]; 15 Hashmap() {memset(hd,-1,sizeof hd),tot=0;} 16 void clear() {for(int i=0; i<tot; ++i)hd[fa[i]]=-1; tot=0;} 17 T2& operator[](T1 x) { 18 int u=x%N; 19 for(int i=hd[u]; ~i; i=nxt[i])if(p[i]==x)return q[i]; 20 nxt[tot]=hd[u],fa[tot]=u,p[tot]=x,hd[u]=tot; 21 return q[tot++]; 22 } 23 int count(T1 x) { 24 int u=x%N; 25 for(int i=hd[u]; ~i; i=nxt[i])if(p[i]==x)return 1; 26 return 0; 27 } 28 }; 29 Hashmap<int,ll> dp[N][M]; 30 Hashmap<int,D> fa[N][M]; 31 Hashmap<int,int> op[N][M]; 32 int getl(int S,int j) {return S>>((j-1)<<1)&3;} 33 int getu(int S,int j) {return S>>(j<<1)&3;} 34 int trans(int S,int j,int d,int r) {return (S&~(15<<((j-1)<<1)))|(d<<((j-1)<<1))|(r<<(j<<1));} 35 int trans(int S,int j,int d) {return (S&~(3<<(j<<1)))|(d<<(j<<1));} 36 int find(int S,int j,int f) { 37 int d=(f==1?1:-1); 38 for(int k=j+d,c=1;; k+=d) { 39 if(getu(S,k)==f)++c; 40 else if(getu(S,k)==(f^3))--c; 41 if(c==0)return k; 42 } 43 return -1; 44 } 45 const int CU=1<<0,CD=1<<1,CL=1<<2,CR=1<<3; 46 const char blank=' ',point='o',hor='-',ver='|'; 47 unordered_set<int> st; 48 void upd(int i,int j,int S,ll x,int o,int fai,int faj,int faS) { 49 // st.insert(S); 50 if(!dp[i][j].count(S))dp[i][j][S]=~inf; 51 if(x>dp[i][j][S]) { 52 dp[i][j][S]=x; 53 op[i][j][S]=o; 54 fa[i][j][S]= {fai,faj,faS}; 55 } 56 } 57 int ans[N*3][M*3]; 58 ll solve() { 59 upd(0,0,0,0,0,-1,-1,-1); 60 int fai=0,faj=0; 61 for(int i=1; i<=n; ++i) 62 for(int j=1; j<=m; ++j) { 63 Hashmap<int,ll> &F=dp[fai][faj],&G=dp[i][j]; 64 G.clear(); 65 for(int k=0; k<F.tot; ++k) { 66 int S=F.p[k],faS=S; 67 ll g=F.q[k]; 68 if(j==1) {if(getl(S,m+1))continue; S<<=2;} 69 int l=getl(S,j),u=getu(S,j); 70 if((i==sx&&j==sy)||(i==tx&&j==ty)) { 71 if(!l&&!u) { 72 upd(i,j,trans(S,j,3,0),g+a[i][j],CD,fai,faj,faS); 73 upd(i,j,trans(S,j,0,3),g+a[i][j],CR,fai,faj,faS); 74 } else if((l==1||l==2)&&!u) { 75 upd(i,j,trans(trans(S,j,0,0),find(S,j-1,l),3),g+a[i][j],CL,fai,faj,faS); 76 } else if(l==3&&!u) { 77 upd(i,j,trans(S,j,0,0),g+a[i][j],CL,fai,faj,faS); 78 } else if(!l&&(u==1||u==2)) { 79 upd(i,j,trans(trans(S,j,0,0),find(S,j,u),3),g+a[i][j],CU,fai,faj,faS); 80 } else if(!l&&u==3) { 81 upd(i,j,trans(S,j,0,0),g+a[i][j],CU,fai,faj,faS); 82 } 83 } else { 84 if(!l&&!u) { 85 upd(i,j,S,g,0,fai,faj,faS); 86 upd(i,j,trans(S,j,1,2),g+a[i][j],CD|CR,fai,faj,faS); 87 } else if(!l&&u) { 88 upd(i,j,S,g+a[i][j],CU|CR,fai,faj,faS); 89 upd(i,j,trans(S,j,u,0),g+a[i][j],CU|CD,fai,faj,faS); 90 } else if(l&&!u) { 91 upd(i,j,S,g+a[i][j],CL|CD,fai,faj,faS); 92 upd(i,j,trans(S,j,0,l),g+a[i][j],CL|CR,fai,faj,faS); 93 } else if(l==1&&u==1) { 94 upd(i,j,trans(trans(S,j,0,0),find(S,j,1),1),g+a[i][j],CL|CU,fai,faj,faS); 95 } else if(l==2&&u==2) { 96 upd(i,j,trans(trans(S,j,0,0),find(S,j-1,2),2),g+a[i][j],CL|CU,fai,faj,faS); 97 } else if((l==2&&u==1)||(l==3&&u==3)) { 98 upd(i,j,trans(S,j,0,0),g+a[i][j],CL|CU,fai,faj,faS); 99 } else if((l==1||l==2)&&u==3) { 100 upd(i,j,trans(trans(S,j,0,0),find(S,j-1,l),3),g+a[i][j],CL|CU,fai,faj,faS); 101 } else if(l==3&&(u==1||u==2)) { 102 upd(i,j,trans(trans(S,j,0,0),find(S,j,u),3),g+a[i][j],CL|CU,fai,faj,faS); 103 } 104 } 105 } 106 fai=i,faj=j; 107 } 108 for(int i=n,j=m,S=0; i;) { 109 int o=op[i][j][S]; 110 ans[i*3-2][j*3-2]=blank; 111 ans[i*3-2][j*3-1]=(o&CU?ver:blank); 112 ans[i*3-2][j*3]=blank; 113 ans[i*3-1][j*3-2]=(o&CL?hor:blank); 114 ans[i*3-1][j*3-1]=a[i][j]; 115 ans[i*3-1][j*3]=(o&CR?hor:blank); 116 ans[i*3][j*3-2]=blank; 117 ans[i*3][j*3-1]=(o&CD?ver:blank); 118 ans[i*3][j*3]=blank; 119 D t=fa[i][j][S]; 120 i=t.i,j=t.j,S=t.S; 121 } 122 for(int i=1; i<=n*3; ++i,puts("")) 123 for(int j=1; j<=m*3; ++j) { 124 if((i+1)%3==0&&(j+1)%3==0)printf("(%3d)",ans[i][j]); 125 else if(ans[i][j]==hor)for(int t=0; t<5; ++t)printf("%c",ans[i][j]); 126 else if(ans[i][j]==ver) { 127 for(int t=0; t<2; ++t)printf(" "); 128 printf("%c",ans[i][j]); 129 for(int t=0; t<2; ++t)printf(" "); 130 } else printf("%5c",ans[i][j]); 131 } 132 return dp[n][m][0]; 133 } 134 int main() { 135 scanf("%d%d%d%d%d%d",&n,&m,&sx,&sy,&tx,&ty); 136 for(int i=1; i<=n; ++i) 137 for(int j=1; j<=m; ++j) 138 scanf("%d",&a[i][j]); 139 printf("%lld\n",solve()); 140 // printf("%d\n",st.size()); 141 return 0; 142 } 143 /* 144 6 5 145 3 2 146 4 4 147 -1 -1 10 10 10 148 10 10 10 -1 10 149 10 10 10 10 10 150 10 10 -1 10 -1 151 -1 10 10 10 10 152 10 10 -1 10 10 153 154 7 8 155 3 2 156 4 4 157 10 10 10 10 10 10 10 10 158 10 10 -1 10 10 10 10 10 159 10 10 10 10 10 10 -1 10 160 10 10 10 10 -1 10 10 10 161 10 10 10 10 10 10 10 10 162 10 10 10 10 -1 10 10 10 163 10 -1 10 10 10 10 10 10 164 165 7 8 166 3 2 167 5 5 168 10 10 10 -10 10 10 10 10 169 10 10 -1 10 10 10 10 10 170 10 10 10 10 10 10 -1 10 171 10 -5 10 10 -1 10 10 10 172 10 10 10 10 10 50 -4 10 173 10 -10 10 10 -1 10 10 10 174 10 -1 10 10 10 10 10 10 175 */