代码已删,只保存了截图。
1.给定n个数字的数组a,数字ai代表物品质量,已知真品质量均相同且高于赝品,求最多有多少赝品。n 1e5。
题意就很怪,按这个题意是不是赝品是确定的,“最多”的限定是多余的。
思路:求a的最大值,假设为x,就是真品质量,求有多少个ai<x,也就是赝品数量。
2.给定n个数字的数组a,每次操作可以将任意一个数字x:分裂成1和x-1;或者分裂成y和z,其中y*z=x。求最少的操作次数使得所有数字均变为1。n 1e5,ai 1e5。
思路:本题可以dp,dp[1]=0,对于i>1,dp[i]=min(dp[i-1]+1,dp[j]+dp[i/j]+1),其中j是2到根号i里所有能被i整除的数。复杂度1e5*sqrt(1e5)
答案就是dp[a[i]]的和,复杂度O(n)
总体复杂度可以认为是O(n sqrt(n))。
3.定义一个括号序列的权值为最长合法括号子序列的长度。给定括号序列,求所有子串的权值和。最大长度1e5。
思路:暴力需要枚举所有子串,再求权值,肯定时间复杂度无法满足。因此考虑对每个括号算贡献。
对于每个左括号,什么时候才能对答案有贡献呢?其实就是它和匹配的右括号同时出现在某个子串中。例如“())(()”,假设下标从1-6,则很显然,序号(1,2)是一对,序号(5,6)是一对。(1,2)出现在1*(6-2+1)个子串中(通过子串左边界和右边界的组合算出),也就是对答案贡献为2*1*5=10。(4,5)同理。因此答案为20。
更规范的公式形式,假设(l,r)匹配,则对答案贡献为2*l*(n-r+1)。
所以只需要先进行一遍括号匹配,找到匹配的括号对,然后对每个括号对计算对答案贡献即可。
时间复杂度O(n)。