2016.6.11纪中模拟赛

题目:

https://jzoj.net/junior/#contest/problems/1312


T1:赤裸裸的水题,直接高精度就行了。


T2:(这题本应放到3或4题上,可老师应该是故意放到这里的吧)考试时我先想到的是贪心,随后我又证明了我那种贪心是不可取的,可是我想都没想下去,就认为这道题是dfs+记忆化了。所以,我就开始打记忆化了,可是题目的条件是100000*100000的,但如果开这么大加上longint的范围不用想都会爆空间,所以自以为是的我开到了8000*8000*longint…………然而……最后……提交上去……还是爆……空间……了。无奈的我决定一定要学会计算空间的方法:

1tb=1024gb 

1gb=1024mb 

1mb=1024kb 

1kb=1024b 

1b=8bit

先要清楚Pascal各种类型的取值范围以及所占字节了。

byte——0~255——1b

integer——-32768~32767——2b

longint——-2147483648~2147483647——4b

int64—— -2^63+1~2^63-1——8b


那么考试中我定义的数组是8000*8000的,再乘以一个4=256000000b=250000kb,明显超过了题目限制的128000kb,所以爆空间只能是吸取一个教训了,下次一定不能再犯。


现在说一下正解:其实也是贪心,如果是搜索记忆化的只能得到50分,而贪心并不是按普通的那一种策略,而是要按二分的贪心策略。亦即,对于当前二分的答案mid,判断mid是否可行,如果可行的话....不可行的话....,这些都很容易想到,举例说明:

如样例:

5 3

9

先排序:

5 3 

1 2 4 8 9

则答案最短为1,最长为9-1=8,然后mid先等于(l+r) div 2=4

判断当前从第i(i=1)个数开始的第j个数与第i个数的差达到mid,则把i更新为j,然后累加tot,j是一个循环变量,从2~n。

然后当最后的tot>=c的时候则代表mid时间在这n个数里是可行的,但不一定是最优解,为了最优解,我们需要贪心的继续往下二分,一些细节的地方就不说了,自己探讨一下吧。


T3:完全水题,赤裸裸的深搜,注意一下边界和常数就行了。


T4:题目大意是指,对于两个序列a,b,依次取a,b序列里的数(题目中有先后顺序)然后求一个题目要求的最优值,这个最优值是指当前如果在取序列a,如果要转移到序列b就要消耗一次转移,总共有w次转移(当w次转移用尽时则不能取其他序列了),a,b两序列总共有t个数,如何选择转移的时机使得取得的数最多。


根据这道题的数据范围,我们可以看到,如果当我们使用搜索的时候,大概只能得60分,而如果我们加上记忆化则能得大概80分,但是如果要满分的话要使用动态规划。


我们可以先看动态规划题目的几个特性——这道题拥有无后效性,亦即,对于1~i的一个顺序序列数的选择不管如何,都不会对以后的选择产生影响,所以就满足了无后效性的原则。其次此问题具有最优子结构,也就是说,当前的第i个数,总会依赖前面i-1个数的最优值,来产生第i个值,也就是问题的最优解等于其子问题的最优解。


知道这道题可以用动态规划的话,我们可以很容易想到用f[i,j]表示前i个数,总共移动j次的最优值。然后,我们这样想——对于当前第i个数,我们只有可能在a树上选数,或者在b树上选数,而对于这两种情况,所得的状态也都两种,第一种不移动,直接移动i-1次,在第..个树上选数,第二种就是移动,移动i次,在第..个树上选数。

设num1=1表示当前第i个数是第一个树上的——num2=0,num2亦然——num1=0.

状态转移方程:

if j mod 2=1 then
	f[i,j]:=max(f[i-1,j-1]+num1,f[i-1,j]+num2)
        	else
        f[i,j]:=max(f[i-1,j-1]+num2,f[i-1,j]+num1);

边界:

if a[i]=1 then f[i,0]:=f[i-1,0]+1 else f[i,0]:=f[i-1,0];

最后输出max{f[t,i]}即可。


当然,我们可以对其进行空间优化——我们看到,其实这里表示的前i个数,是可以省略的,我们可以直接用f[i]表示移动i次所能获得的最优值。

而边界需有所改变,f[0]表示的必须是当前第枚举到i个数所产生的值,也就是需在动态规划做出决策里面来进行调整边界, 不能在动态规划之外的部分先把边界算好。

其次动态转移方程也变得简略一些:

f[j]={f[j-1]}+1 | j mod 2=a[i]-1


这里的a[i]-1和j mod 2的关系,就不详细讲了,请自己探讨一下。

最后输出max{f[i]}即可。


这样优化之后空间复杂度就由原来的O(n·m)变成了O(m),空间复杂度和编程复杂度都大大缩小了,而如果想缩小时间复杂度就可以在输入的时候进行动规——这样就三重提高了,可见动态规划的优化是多么重要,当数据极端化的时候往往能带给不一样的收获。(二维也可以用滚动数组)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值