E02 线性DP P1216 数字三角形
P1216 [IOI 1994 / USACO1.5] 数字三角形 Number Triangles - 洛谷
// 线性DP O(n^2) #include<bits/stdc++.h> using namespace std; const int N=1005; int n,a[N][N],f[N][N]; //f[i,j]表示以 (i,j) 为顶点的子三角形,路径和的最大值 int main(){ scanf("%d",&n); for(int i=1; i<=n; i++) for(int j=1; j<=i; j++) scanf("%d",&a[i][j]); for(int i=n; i>=1; i--) for(int j=1; j<=i; j++) f[i][j]=max(f[i+1][j],f[i+1][j+1])+a[i][j]; printf("%d\n",f[1][1]); }
P1004 [NOIP 2000 提高组] 方格取数 - 洛谷
等价于两人同时走,并且走相同步数。条件:i+j == x+y
f[i,j,x,y]表示两人从 (1,1) 同步走到 (i,j)、(x,y) 的路径和的最大值
// 线性DP O(n^4) #include<iostream> using namespace std; const int N=11; int n,x,y,a[N][N]; int f[N][N][N][N]; //f[i,j,x,y]表示两人从 (1,1) 同步走到 (i,j)、(x,y) 的路径和的最大值 int main(){ cin>>n; while(cin>>x>>y>>a[x][y],x); for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) for(int x=1; x<=n; x++) for(int y=1; y<=n; y++) if(i+j==x+y){ f[i][j][x][y]=max(max(f[i-1][j][x-1][y],f[i-1][j][x][y-1]), max(f[i][j-1][x-1][y],f[i][j-1][x][y-1]))+a[i][j]+a[x][y]; if(i==x && j==y) f[i][j][x][y]-=a[i][j]; //同一点去重 } cout<<f[n][n][n][n]; }
利用约束条件,降维优化,令 i+j=x+y=k 表示走的步数
f[k,i,x]表示共走了k步,两人分别走到i行x行,取数的最大值
// 线性DP O(n^3) #include<bits/stdc++.h> using namespace std; const int N=11; int n,x,y,a[N][N],f[N+N][N][N]; int main(){ cin>>n; while(cin>>x>>y>>a[x][y],x); for(int k=2; k<=n+n; k++) //走了k步 for(int i=1; i<=n; i++) //走到i行 for(int x=1; x<=n; x++){ //走到x行 int j=k-i,y=k-x; if(j>=1&&j<=n&&y>=1&&y<=n){ f[k][i][x]=max(max(f[k-1][i-1][x-1],f[k-1][i-1][x]), max(f[k-1][i][x-1],f[k-1][i][x]))+a[i][j]+a[x][y]; if(i==x) f[k][i][x]-=a[i][j]; } } cout<<f[n+n][n][n]; }
P1006 [NOIP 2008 提高组] 传纸条 - 洛谷
// 线性DP O(n^3) #include<bits/stdc++.h> using namespace std; const int N=55; int m,n,a[N][N]; int f[N+N][N][N]; int main(){ cin>>m>>n; for(int i=1; i<=m; i++) for(int j=1; j<=n; j++) cin>>a[i][j]; for(int k=2; k<=m+n; k++) //步数 for(int i=1; i<=m; i++) //行 for(int x=1; x<=m; x++){ //行 int j=k-i, y=k-x; if(j<1 || j>n || y<1 || y>n) continue; f[k][i][x]=max(max(f[k-1][i-1][x-1],f[k-1][i-1][x]), max(f[k-1][i][x-1], f[k-1][i][x]))+a[i][j]+a[x][y]; if(i==x) f[k][i][x]-=a[i][j]; } cout<<f[m+n][m][m]; }
 
                    
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号