[DP] Jzoj P3198 蚂蚁寻路
作者:互联网
题解
- 看完题目,然后随便画一画蚂蚁的行走路径可以发现,它的行走路径一定是
- 类似于这种形状的,也就是一共有2*k+1个长方形组合形成的(k次分隔)
- 那么答案就是要求2*k+1个矩阵内所有数之和最大值,考虑一下dp
- 设f[i][j][k][h]为当前这个矩阵的右下角(i,j),是第k个矩阵,高度为h的最大值,g[i][j][k][h][0/1]为当前这个矩阵的右下角(i,j),是第k个矩阵,高度大于等于/小于h的最大值
- 很容易就得出状态转移方程为f[i][j][k][h]=max(f[i][j-1][k][h],g[i][j-1][k-1][h][k%2])+sum[i][j]-sum[h-1][j](sum[i][j]表示第j列的前i行的和)
- 什么意思呢?
- ①f[i][j-1][k][h]也就是说矩阵还是原来那个,只是列多了一列
- ②第二个就是从第j列开始新开一个新的矩阵,那么矩阵是一高一低分布的,这个矩阵是高是低取决于第k-1个是高是低
- 按照定义的性质从高到低和从低到高分别扫一遍,转移为g[i][j][k][h][0]=max(g[i][j][k][h -1][0],f[i][j][k][h -1]),g[i][j][k][h][1]=max(g[i][j][k][h+1][1],f[i][j][k][h+1])
代码
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 using namespace std; 5 const int N=210,inf=1e9; 6 int n,m,k,a[N][N],s[N][N],f[N][N][N],g[N][N][N][3],ans=-inf; 7 int main() 8 { 9 scanf("%d%d%d",&n,&m,&k),k=k*2+1; 10 for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) scanf("%d",&a[i][j]),s[i][j]=s[i-1][j]+a[i][j]; 11 for (int i=1;i<=k;i++) for (int j=1;j<=n;j++) f[0][i][j]=g[0][i][j][0]=g[0][i][j][1]=-inf; 12 for (int i=1;i<=n;i++) 13 for (int j=1;j<=m;j++) 14 { 15 for (int p=1;p<=k;p++) 16 { 17 for (int q=i;q>=1;q--) f[j][p][q]=max(f[j-1][p][q],g[j-1][p-1][q][p%2])+s[i][j]-s[q-1][j]; 18 g[j][p][1][0]=-inf; 19 for (int q=2;q<=i;q++) g[j][p][q][0]=max(g[j][p][q-1][0],f[j][p][q-1]); 20 g[j][p][i][1]=-inf; 21 for (int q=i-1;q>=1;q--) g[j][p][q][1]=max(g[j][p][q+1][1],f[j][p][q+1]); 22 } 23 ans=max(ans,max(f[j][k][i],g[j][k][i][0])); 24 } 25 printf("%d",ans); 26 }
标签:蚂蚁,Jzoj,int,max,矩阵,P3198,右转,左转,DP 来源: https://www.cnblogs.com/Comfortable/p/10335903.html