bzoj3111 [Zjoi2013]蚂蚁寻路
2013-04-26 21:19
405 查看
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
不行,这种2D的dp我做得实在是太少了...
这个题我一开始只能想出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
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #define maxn 120 #define inf 1000000000 using namespace std; int f[maxn][24][maxn],a[maxn][maxn],s[maxn][maxn],mx[maxn][24][maxn][3]; int n,m,p,ans; int main() { scanf("%d%d%d",&n,&m,&p); p=p*2+1; 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]; for (int i=1;i<=n;i++) for (int k=1;k<=p;k++) f[0][k][i]=mx[0][k][i][0]=mx[0][k][i][1]=-inf; ans=-inf; for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) { for (int k=1;k<=p;k++) { for (int h=i;h;h--) 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]; mx[j][k][1][0]=-inf; for (int h=2;h<=i;h++) mx[j][k][h][0]=max(mx[j][k][h-1][0],f[j][k][h-1]); mx[j][k][i][1]=-inf; for (int h=i-1;h;h--) mx[j][k][h][1]=max(mx[j][k][h+1][1],f[j][k][h+1]); } ans=max(ans,max(f[j][p][i],mx[j][p][i][0])); } printf("%d\n",ans); return 0; }
不行,这种2D的dp我做得实在是太少了...
相关文章推荐
- bzoj3111: [Zjoi2013]蚂蚁寻路
- [DP] BZOJ 3111 [Zjoi2013]蚂蚁寻路
- bzoj 3111: [Zjoi2013]蚂蚁寻路(DP)
- 3111: [Zjoi2013]蚂蚁寻路 - BZOJ
- BZOJ 3111 [Zjoi2013]蚂蚁寻路
- bzoj 3111: [Zjoi2013]蚂蚁寻路
- bzoj 3111: [Zjoi2013]蚂蚁寻路 动态规划
- 【洛谷3335】【ZJOI2013】蚂蚁寻路
- [BZOJ 3111] ZJOI 2013 蚂蚁寻路 · 动态规划
- 数据结构(树套树):ZJOI 2013 K大数查询
- 3110: [Zjoi2013]K大数查询
- 3110: [Zjoi2013]K大数查询
- bzoj3110: [Zjoi2013]K大数查询 【cdq分治&树套树】
- 【BZOJ3110】【ZJOI2013】K大数查询
- [期望 DP || 高斯消元 KMP] BZOJ 3213 [Zjoi2013]抛硬币
- Bzoj3110 [Zjoi2013]K大数查询
- bzoj 3110 [Zjoi2013]K大数查询(树套树)
- BZOJ 3110 ZJOI 2013 K大数查询 树套树(权值线段树套区间线段树)
- 【BZOJ3110】【Zjoi2013】K大数查询
- BZOJ-3110-K大数查询-ZJOI2013-整体二分