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 */
View Code

 

posted @ 2020-07-26 19:51  jrltx  阅读(269)  评论(0编辑  收藏  举报