写在前面:这一套比赛听说是一位OI界的神犇出的题,果然质量很高啊,要好好总结。
T1:
It very simple.
You can 排序,and 模拟 and AC.
T2:
一眼知道是DP.
关键没想到怎么去无后效性.
很明显只需要倒着推,因为当你在倒着推做到第i个的时候,i+1~n都是没有变过的,所以并不会对i产生影响,也就是去除了无后效性.
明白了去无后效性后,想想状态怎么设置.
对于第i段路的高度,要么它就不与前面的交换,要么就交换.
则很明显可以设
f[i,0]表示第i段路不换的最优值.
f[i,1]表示第i段路换的最优值.
希望状态转移方程各位能自己推推,不难.
{
转移如下:
如何计算f[i,0]呢?
很明显,至于f[i+1,0/1]有关.
f[i,0]=min{f[i+1,0]+abs(a[i]-a[i+1]),f[i+1,1]+abs(a[i]-a[i+2])}
为什么这样呢?
因为如果第i+1个不交换,那么第i个就要走到第j个,花费为abs(a[i]-A[I+1])
而如果第i+1个交换了,则不管它怎么换,换到哪里,花费都是abs(a[i]-a[i+2]),因为i+2会移到i+1这个位置。
然而f[i,0]应该是最好求的,那么f[i,1]怎么求呢?
因为我们不知道第i个位置它要移到哪去,所以,我们可以枚举.
设第i个数移到j这个位置
i移到j这个位置,则i+1~j的所有位置都往前移了一个格,i会与j产生一个新的差
记为x1=abs(a[i]-a[j])
而i+1~j他们之前互相会产生一个差,我们要求这些差的和,很明显用前缀和可以求,记为x2=Sj-S(i+1)
那么x1和x2是不变量,而对于第j+1位,如果它不换,则答案=f[j+1,0]+x1+x2+abs(a[i]-a[j+1])
如果换了,则答案=f[j+1,1]+x1+x2+abs(a[i]-a[j+2]),很明显答案取两者较优,至于为什么,则与求f[i,0]的思路是类似的,自行思考.
}
T3:
考试时打的暴力,但正解非常巧妙.
可以把一个矩阵里的相同类型数字看做一些点,那么这些点之间互隔的距离会产生一些类似矩阵,把这些矩阵的大小累加即为答案.
f[i,0]表示第i个数当前最靠左的位置.
f[i,1]表示第i个数当前次靠左的位置.
很明显,第一次遇到i这个数,我们需要累加答案,是(m-j+1)*(n-i+1){i表示行,j表示列},并记录f[i,0],以及把f[i,1]的值赋值为M+1,方便第二次遇到i时计算.
而第二次遇到i时,
假设是在f[i,1]的左边,则需要减去答案 (f[i,1]-j)*(n-i+1),并记录f[i,1].
假设是在f[i,0]的左边,那就f[i,0]与f[i,1]一起更新,并累加答案(f[i,0]-j)*(n-i+1),再减去答案(f[i,1]-f[i,0])*(n-i+1).
以此类推……
这样子,则可以求出答案,这需要自己去意会,理解一下,就不多说了。
T4:
一道很巧的规律题:
当前加入的第i个数,b[i]只有可能与b[i-1]的差在0~2之间,why?
Because——
前i-1个数,因为要求互不相等,所以如果前i-1个数当中有一个i-1的且第i个增加的数<=i则 b[i]=b[i-1]+2
如果前i-1个数当中有一个i-1但第i个数>i,则 b[i]=b[i-1]+1
当=0的时候,很明显对答案是没贡献的.
接下来分类讨论:
当b[i]=b[i-1]+2的时候,
前面i-1个数本来能放i-1个<=i的数,但因为前面有b[i-1]个<=i-1的数,所以前i-1个数能放的<=i的个数为i-1-b[i-1]
而第i个位置本来能放i个<=i的数,但与之前的原因一样,只能放i-b[i-1]个,但又由于前i-1个数又多放了一个<=i的数,所以第i个位置只能放的个数需要再减1.当b[i]=b[i-1]+1的时候,
第i个数能放i-b[i-1]个<=i的数,前i-1个位置能放i-1-b[i-1]的数,方案数是累加的,因为一次只能放一个.
规律如下:
当b[i]-b[i-1]=1:i-b[i-1]-1+i-b[i-1]
当b[i]-b[i-1]=2:(i-b[i]-1)*(i-b[i]-1)
最后高精度即可.