[Codeforces Round #431]简要题解
来自FallDream的博客,未经允许, 请勿转载,谢谢。
好久没写cf题解了zzz
代码比较丑不贴了,cf上都可以看
Div2A.
给你一个长度为n(n<=100)的序列 判断是否可以分成奇数个长度是奇数,且第一个和最后一个都是奇数的子串
当时想都没想就交了个dp
发现实际上满足n是奇数,a1和an都是奇数即可。
Div2B
给n(n<=1000)个点,第i个点坐标(i,ai),问是否可以用两条平行线恰好穿过所有的点
有一条线肯定通过12,或者23或者13,枚举情况分别判断即可。
Div1A
将两个串合并的费用是所有字母在两边的个数的乘积之和,要求构造一个最小费用是n(<=100000)的串。
不同字母的费用分开计算,m个相同字母的费用是m(m-1)/2 贪心一下就好了。
Div1B
有n(<=100000)个点,第i个点在ti时间之后从x或者y轴的pi的位置开始向另一个轴正方向移动,两个点相撞会反弹,求每个点最终位置。
首先根据pi-ti不同分开处理
然后对于每个点求出有多少个pi-ti相同的,并且从另一个方向飞过来的点,同时求出有多少个pi-ti相同的,并且和他同一个轴的坐标比他大的点。
两种点都会让他反弹,根据哪种比较多判断最终飞的方向,可以用一个线段树查k大来获得最终位置。
Div1C
维护一个长度为n(<=100000)的序列,支持单点修改,查询区间所有权值最大位置-最小位置的和,m<=100000。
用set维护每种权值的出现位置,每个数和它的上个数都在区间内时会产生(距离)的贡献。
然后就变成了二维单点改,查询矩形和的问题,套树貌似空间不太够,cdq分治比较稳。
Div1D
题目比较复杂,可以自己看,不解释了。
可以看出这道题肯定是DP,因为一个图就等于一条边加上很多个“桥”,每个桥又由两个图组成,有重复的子问题。
用f[i][j]表示用i次操作获得一个流量是j的桥的方案数。
用g[i][j]表示用i此操作获得一个流量是j的图的方案数。
f[i][j] * f[k][l] 转移到 -> g[i+k+1][min(j,l)]
然后因为同构的关系同一个f[i][j]一起转移
从n个里选出k个,可以重复的方案数是C(n+k-1,n-1)
动态维护这个组合数,在转移的时候 枚举选择k个f[i][j],则g[i'][j']+=f[i'-k*i][j'-k*j] * C(f[i][j]+k-1,f[i][j]-1)