Newnode‘s NOI 模拟赛 第二题 (单调dp)
2018-03-07 17:33
363 查看
第二题
问题描述样例输入 1
3 2
*#
#*
##
样例输出 1
2
样例输入 2
4 5
*####
*####
*####
#* * * #
样例输出 2
3
提示
对于20%的数据n,m<=5;
对于50%的数据满足n,m<=500;
对于100%的数据满足2<=n,m<=2000。
题意要求用每次消去正或反的L形的三个格子,消除所有的关键格子,需要的最小步数。
显然每一列只需要关心最上面一个关键格子的位置就行了。
因此令A[i]A[i]表示第ii列最上面一个关键格子是从下往上数的第几个格子。
先考虑暴力的dp,令F[i][j]F[i][j]表示前ii列,前i−1i−1列已经消完,第ii列还需要消jj个格子的最优步数。
那么转移的时候枚举第ii列消去了kk个反L形,有
F[i][j]=min(F[i−1][k+2(A[i]−j−2k)]+k+A[i]−j−2k)F[i][j]=min(F[i−1][k+2(A[i]−j−2k)]+k+A[i]−j−2k)
k+2(A[i]−j−2k)k+2(A[i]−j−2k)表示消去第ii行时,第i−1i−1行会被消去的数量,也可以从F[i−1]F[i−1]第二维更小的位置转移过来,但显然不会更优。另外,F[i][A[i]+1]−F[i][n]F[i][A[i]+1]−F[i][n]都赋值为F[i−1][0]F[i−1][0]
这个dp是O(n3)O(n3)的,需要优化。
考虑一下每次转移时F[i][j]F[i][j]和F[i][j+1]F[i][j+1]分别在kk等于多少时取得最优值,一个结论是F[i][j+1]F[i][j+1]取得最优值的kk一定小于等于F[i][j]F[i][j]取得最优值的k,这个结论脑补一下就能理解。因为需要消去的块变少了,那么相应的操作数一定是不增的。
容易得到F[i]F[i]是随着j变大而单调不增的。
再观察一下可以发现,在jj确定的时候,F[i−1][2A[i]−2j−3k]+A[i]−j−kF[i−1][2A[i]−2j−3k]+A[i]−j−k的取值是单峰的。因为F[i−1][2A[i]−2j−3k]F[i−1][2A[i]−2j−3k]随k的减小是不增的,A[i]−j−kA[i]−j−k是单增的,因此它是单峰的。
那么我们得到了一个很好的性质,即F[i][j]F[i][j]的转移是单峰的,并且峰的位置是单调的。
因此我们就可以将枚举k的复杂度变成均摊O(1)O(1)的了。只需要每次记录一下最优的k取值,讨论j+1j+1时直接从这个最优取值开始,如果k−1k−1不能更优就breakbreak就行了。
总时间复杂度O(n2)O(n2)
代码:
#include<stdio.h> #include<iostream> #include<algorithm> #include<cstring> #define N 2005 using namespace std; int n,m,F ,A ; char map ; int main() { int i,j,k,x,id; scanf("%d%d",&n,&m); for(i=1;i<=n;i++)scanf("\n%s",&map[i][1]); for(i=1;i<=m;i++) { for(j=1;j<=n;j++)if(map[j][i]=='*')break; A[i]=n+1-j; } memset(F,60,sizeof(F)); for(i=0;i<=n;i++)F[0][i]=0; for(i=1;i<=m;i++) { id=A[i]>>1; for(j=0;j<=A[i];j++) { id=min(id,A[i]-j>>1); for(k=id;k>=0;k--) { x=k+(A[i]-j-2*k<<1); if(x>A[i-1])x=A[i-1]; if(F[i][j]>=F[i-1][x]+A[i]-j-k)id=k,F[i][j]=F[i-1][x]+A[i]-j-k; else break; } } for(j=A[i]+1;j<=n;j++)F[i][j]=F[i-1][0]; } printf("%d",F[m][0]); }
相关文章推荐
- NOI Newnode模拟题 第二题 DP 单调性优化 三分法
- 10.11 NOIP模拟赛 DP + 线段树 + DP + 单调队列
- BZOJ1499 [NOI2005]瑰丽华尔兹 【单调队列优化dp】
- 【DP】【单调队列】【NOI2005】瑰丽华尔兹
- [BZOJ1499][NOI2005]瑰丽华尔兹 dp+单调队列
- bzoj1499 [NOI2005]瑰丽华尔兹(luoguP2254)(dp+单调队列)
- 【bzoj1499】[NOI2005]瑰丽华尔兹 【单调队列优化dp】
- BZOJ 1499 [NOI2005] 瑰丽华尔兹 | 单调队列优化DP
- [BZOJ 1499][NOI 2005]瑰丽华尔兹(DP+单调队列优化)
- bzoj1499[NOI2005]瑰丽华尔兹 单调队列优化dp
- bzoj 1499: [NOI2005]瑰丽华尔兹【dp+单调队列】
- [NOI 2005] 瑰丽华尔兹:dp+单调队列
- 【noi2005试题】瑰丽华尔兹 单调队列优化DP
- 【bzoj1499】[NOI2005]瑰丽华尔兹(dp+单调队列优化)
- BZOJ 4199: [Noi2015]品酒大会/UOJ #131. 【NOI2015】品酒大会 后缀自动机 树形dp / 后缀数组 单调栈
- BZOJ3242 [Noi2013]快餐店 【环套树 + 单调队列dp】
- Bzoj - 1499 [Noi2005] 瑰丽华尔兹 [DP][单调队列优化]
- [DP 暴力 || ST表 || 单调队列] BZOJ 1499 [NOI2005]瑰丽华尔兹
- NOIP2017模拟赛 龙珠(dp+单调队列优化)
- bzoj1499 [NOI2005]瑰丽华尔兹 (单调队列优化DP)