算是有那么一点点遗憾的,考砸了,状态很差,该出的题没有出。
达成成就:做不到4题就退队flag秒破。
考试结束后和岑巨说,自己每次到了比较重要的比赛或者考试的时候,总会有点失眠。
希望到区域赛的时候能克服一下吧,精力不足很致命啦。
(然后谢大神补刀:BB这么多干嘛,你个菜逼(orzorz
好了下面主要是做题的过程和思路。
流水账:
开场看A,发现见过,但是忘记怎么写了,于是跳B;
看B,看不懂,跳C;
C可做,(思路见下面),敲之,TLE,剪枝后ac;
然后再开D,可做,(思路在下面),敲之wa,找不到bug所以弃了;
看E,暂时没思路;
看F,可做,但是A显然比F简单,回过头做A;
A题过了之后,E题不想开,F题无限wa,B题不会推,欢声笑语中GG退队。
A思路:
首先记录一下字符串中,各个字符出现的次数,找到出现次数最多的那个字符出现了多少次,设为cnt吧。
那么,如果 cnt+p<=n ,该串的答案ans一定是cnt+p;
否则,假设多余了pp个操作,我可以拿这pp个操作随便换,最后一步换到需要的字符,那么ans=n;
有一个例外,比如 s=“aaa” p=1 ,这个情况下,答案为2,而不是3。
可以归纳为:当串中只有一种字符,并且p=1时,ans=n-1。
这题的出题人岑巨已经回家躲着了哈哈哈哈哈。。。
B思路:
首先更新一下最高赔率的值,赢的赔率为w,平局赔率为d,输的赔率为l,由于一定要赢,三个都得买。
那么,根据赔率:
买1/w元的赢,如果中了可以得到1元;
买1/d元的平,如果中了可以得到1元;
买1/l元的输,如果中了可以得到1元;
那么最后无论如何我都能得到1元。
如果**(1/w+1/d+1/l)<1**,说明我花费小于收获。
我不管,这题我得甩锅给没睡好。
C思路:
根据题意一步一步来便可,看到数据范围,字符串长度等于200,不妨直接枚举一下获胜一局需要多少积分,
然后枚举一下赢得多少局算获胜。容易知道需要的积分的范围可以设为[1,len],那么一共最多能玩多少局呢?
这里一开始我写的[1,len]局,超时了。
剪枝:一局需要i积分,那么满足i*j<=len,区间可以修改为[1,len/i]。
至于暴力枚举,就不多说了。
D思路:
栅栏有横竖两种,我们可以从输入中统计一下每个横向的栅栏能够阻止多少对猪,每个纵向能够阻止多少对猪。
那么,如果这根栅栏有贡献了,一定要算进去。
如果给的栅栏数足够了,直接输出答案。如果给的不够,那么直接对贡献排序,把栅栏建在贡献高的位置便可。
个人认为CD应该放在AB的位置。难度较之简单一丢丢吧。
E思路:
因为是有向边,要从各个点到达x,又要回到各个点去,
不妨从x点正向和反向跑2次dijkstra最短路,貌似要加堆优化。
也就是建2个邻接表,一个表存正向边的图,一个表存反向边的图,二者最短路相加,
找到最大值便可。
F思路:
动态规划或者记忆化搜索都能做。
设dp[i][j]
表示对[1,i]这个区间,拆分为j段,那么,
dp[n][m]
就代表对区间[1.n]拆分为m段的结果。
如何递推呢?
首先初始化dp数组,令所有的dp[i][j]=-inf
(考试的时候我初始化为0了,如果要初始化为0,到时候的边界就要特别注意了。不如直接初始化-inf
)
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
for(int k=1;k<i;k++){
if(k==i-1)dp[i][j]=max(dp[i][j],dp[k][j-1]+a[i]);
else dp[i][j]=max(dp[i][j],dp[k][j-1]+abs(a[i]-a[k+1])*(i-k));
}
}
}
dp[k][j-1]表示区间[1,k]划分j-1段的最大值。
dp[i][j]可以由dp[k][j-1]转移而来。转移方程如上。
没有事后诸葛亮啦,及时总结一下总是有好处的叭。
下次再遇到A题这出题人我会替大家收拾他的(岑巨我说着玩的您别当真…)
经验:
1.保证好睡眠
2.卡题要开新题,尤其是个人赛没有人给你debug
3.提升各方面奇淫姿势
溜了溜了~