前言
榜上那个冒着蓝光的就是我……
提交记录跟答辩一样……
\(\color{#F8BBD0}Heldivis %%%%%%%%%%%%%%%%%%%\)
吐槽一下,虽然挂着 DP 专题赛的名字,但除了 T1 T3 以外,全是记搜题(虽然好像只有四道题来着)。
T1
签到题,\(n\) 范围很小,先用区间 dp 求出任意区间达到最终状态所需的最小代价,然后再用一个 dp 计算答案。
最开始没加 freopen
,一直 RE,我是废物。
放一下核心的转移方程:
if(s[l-1]==s[r-1])dp[l][r]=min(dp[l][r],dp[l+1][r-1]);
else dp[l][r]=min(dp[l][r],dp[l+1][r-1]+min(w[l],w[r]));
ans[i]=min(ans[i],ans[j]+dp[j+1][i]);
T2
看一眼上面的提交记录就知道多测不清空的危害了。
记忆化搜索, dfs 函数里面放三个参数,代表当前剩下的区间和对手拿走的青色石头的数量,知道区间以后,当前是谁该拿石头已经确定,所以不用新增参数。
然后用一个前缀和维护(最开始用了缺省源里面的树状数,后来又 WA 又 T 才发现自己是傻子)计算当前自己拿的青色石头的数量,进行递归时,自己与对手身份互换,所以应该用自己的数量配上当前选择去传参。
然后用一个三维数组记忆化,两个数字判断当前输赢状况,边界的话 \(\gt k\) 即可。
然后我记忆化数组没有清空,收获满屏 RE(IOI赛制没有罚时,lalala)。
写完以后发现只有 50pts,然后不知道改了什么就 \(\color{green}AC\) 了,后来才知道是老邱改了时限。。。
代码是一坨,不放了,太丢人。
T3
不会写,BFS 拿了 50pts。
对于正解,因为字符串里面只有三种字符,所以用一个四维状态代表三种字符选择的数量和当前操作次数。
先预处理出来三种字符的前缀和和出现的所有位置。
四重循环分别枚举四种状态,然后每次分别对三种字符操作,计算出当前状态下另外两种字符在当前状态下还可以选择的次数。
如果选择当前字符,那么能够产生的贡献就是另外两种还可以选择的字符分别与当前这个字符进行交换产生的方案数,具体的,就是两种字符在当前区间内出现次数的和。计算好状态以后让新状态累加当前状态数量即可。
三种都枚举完以后,判断是否满足最终条件并累加到最终答案上面即可。
放一下核心代码(为了减少博客空间复杂度,压行压的很丑):
dp[0][0][0][0]=1;
for(int i=0;i<=cnt[1];i++)for(int j=0;j<=cnt[2];j++)
for(int k=0;k<=cnt[3];k++)for(int c =0;c <=500;c ++)
{
d[1]=i;d[2]=j;d[3]=k;
for(int num=1;num<=3;num++)
{
if(d[num]>=cnt[num])continue;
int now=pos[num][d[num]],cost=0;
for(int l=1;l<=3;l++)if(l!=num)cost+=max(0,sum[l][now]-d[l]);
if(c+cost<=500)dp[i+(num==1)][j+(num==2)][k+(num==3)][c+cost]+=dp[i][j][k][c];
}
if(i==cnt[1]&&j==cnt[2]&&k==cnt[3]&&c<=kk)ans+=dp[i][j][k][c];
}
T4
ABC 原题+ ICPC热身赛原题,无话可说……
输出 -1 有 18pts,脑残特殊性质写了再加 20pts,然后我脑残 max 写了个 min,没调出来,导致 rk2 -> rk5,呜。
正解是爆搜+记忆化,复杂度证明得很LC,没毛病。
先离散化,dfs 里面传三个参,代表当前已经可以到达的区间和当前在区间左端点还是右端点。
用一个数组表示当前是否已经拿到对应的锤子,大力分讨即可。
代码实在压不下来,所以不放了。
结语
军训不用去
天天玩电脑
————牢邱
标签:字符,专项,练习赛,min,状态,2024736DP,当前,区间,dp
From: https://www.cnblogs.com/Lydic/p/18326760