bzoj3111 [Zjoi2013]蚂蚁寻路

zjoi2013的题终于做完了,拖了好久,觉得这份题质量挺高的,而且代码量都不是很大,zj的题还是比较注重思路的,而且都可以有不同的解法,甚至可以骗分= =。

这个题我一开始只能想出N^4的,后来参考某神的题解发现我多出来的那一维完全是没有用的......但是我还是想总结一下思路,毕竟这种2D的DP做的比较少,以免以后忘掉。

首先经过一些列的简化我们发现这个题实际就是求个凹凸不平的形状中的最大值,也就是一堆高度参差不齐的子矩形的和,这些子矩阵同底,高满足一高一低,一共要这样变2k次,也就是一共有2*k+1个矩形。

设f[i][j][k][h]表示以[i][j]为右下角的子矩阵,是当前的第k个子矩阵,最高点的坐标是h的最大和,然后mx[i][j][k][h][0/1]表示···最高点坐标不大于/不小于h的最大和。

于是有以下转移:

  f[i][j][k][h]=max{  f[i][j-1][k][h] , mx[i][j-2][k-1][h][k%2]  }+s[i][j]-s[h-1][j]

  mx[i][j][k][h][0]=max{  mx[i][j][k][h-1][0] , f[i][j][k][h-1]  }

  mx[i][j][k][h][1]=max{  mx[i][j][k][h+1][1] , f[i][j][k][h+1]  }

  ans 用max{  f[j][p][i] , mx[j][p][i][0]  }来更新

注意边界条件f[0][k][i]=mx[0][k][i][0]=mx[0][k][i][1]=-inf;

ant
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstring>
 6 #define maxn 120
 7 #define inf 1000000000
 8 using namespace std;
 9 int f[maxn][24][maxn],a[maxn][maxn],s[maxn][maxn],mx[maxn][24][maxn][3];
10 int n,m,p,ans;
11 
12 int main()
13 {
14     scanf("%d%d%d",&n,&m,&p);
15     p=p*2+1;
16     for (int i=1;i<=n;i++)
17         for (int j=1;j<=m;j++)
18             scanf("%d",&a[i][j]),s[i][j]=s[i-1][j]+a[i][j];
19     for (int i=1;i<=n;i++)
20         for (int k=1;k<=p;k++)
21             f[0][k][i]=mx[0][k][i][0]=mx[0][k][i][1]=-inf;
22     ans=-inf;
23     for (int i=1;i<=n;i++)
24         for (int j=1;j<=m;j++)
25         {
26             for (int k=1;k<=p;k++)
27             {
28                 for (int h=i;h;h--)
29                     f[j][k][h]=max(f[j-1][k][h],mx[j-1][k-1][h][k%2])+s[i][j]-s[h-1][j];
30                 mx[j][k][1][0]=-inf;
31                 for (int h=2;h<=i;h++)
32                     mx[j][k][h][0]=max(mx[j][k][h-1][0],f[j][k][h-1]);
33                 mx[j][k][i][1]=-inf;
34                 for (int h=i-1;h;h--)
35                     mx[j][k][h][1]=max(mx[j][k][h+1][1],f[j][k][h+1]);
36             }
37             ans=max(ans,max(f[j][p][i],mx[j][p][i][0]));
38         }
39     printf("%d\n",ans);
40     return 0;
41 }

不行,这种2D的dp我做得实在是太少了...

转载于:https://www.cnblogs.com/zig-zag/archive/2013/04/26/3045836.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值