T1
题面:


很水的一道题,硬生生被题目搞没了 50pts……
首先我要说明一件事:这个题目实际上就是把按照第 iii 位四舍五入的过程给你仔细地说明了一下,代码非常好写,这里我不多展开。
然后我来说一说我被题目搞没 50pts 是为什么。注意看这句话:
需要注意的是,第 111 位即使进位,也不会改变我们上面约定的位数的编号规则。
这句话很好理解嘛,就是编号一直保持 1,2,…,k1,2,\dots,k1,2,…,k 嘛,不会因为第一位进位变成 0,1,2,…,k0,1,2,\dots,k0,1,2,…,k 或者 1,2,…,k,k+11,2,\dots,k,k+11,2,…,k,k+1。
然后我们再来看输出:
你需要具体输出每一步后的结果,从原数开头。
现在我们来思考一个事:这个原数开头是指从 1→k1\to k1→k 还是 0→k0\to k0→k。
首先解释一下这个 a0a_0a0 是什么:a0a_0a0 就是第一位进位后的值。前面说了:第一位即使进位,编号也不变。那不就是最高位的编号永远是 111 咯?那这么说输出也就只需要输出 1→k1\to k1→k 就行了?但是这明显不对啊,原数不是还有一个 a0a_0a0 吗?这一位不输出?
然后我就就着这个问题思考了一个小时,最终我选择:不输出 a0a_0a0。然后没了 50pts……
所以这真的不是我的错 ,实在是题目太……抽象了。
T2
题面:


首先这题很容易想到二维 DP,于是我们可以写出一份超级暴力的代码:
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
for(int k=0;k<i;k++)
{
for(int l=1;l<=m;l++)
{
if(a[i][j]>a[k][l])
{
dp[i][j]=max(dp[i][j],dp[k][l]+1);
}
}
}
}
}
但是很明显这份代码过不了,稍微一算时间复杂度就知道:这代码能过我吃。
那怎么优化呢?这里有很多大佬会说:用线段树啊!线段树不是直接秒了吗。这里确实可以用线段树,不过本蒟蒻太菜了,想到可以用线段树但写不来,于是我用了三个 DP。
在这之前,我们要先搞清楚如果要用线段树大致该怎么写:首先肯定对于每一排要求区间最大值,然后还要把每一行的区间最大值再求一次区间最大值,这样时间复杂度才稍微正常一点(差不多是 O(nmlognlogm)O(nm\log n\log m)O(nmlognlogm) 左右),那现在我们不会线段树,我们要用数组去模拟这个区间最大值,该怎么办呢?我的想法是这样的:
- 定义
g[i][j]表示在第 iii 行且在第 jjj 列左边的所有dp值中的最大值。 - 定义
f[i][j]表示在第 iii 行上面且在第 jjj 列左边的所有g值中的最大值。
然后我们就可以写出转移方程:
dpi,j=max{ dpi,j,fi,j+1}dp_{i,j}=\max\{dp_{i,j},f_{i,j}+1\}dpi,j=max{ dpi,j,fi,j+

最低0.47元/天 解锁文章
1072

被折叠的 条评论
为什么被折叠?



