题解 洛谷 P5329 【[SNOI2019]字符串】

这道题老师有一天断了网让我们做,然后线下测评开了2s。。。

当时我是手打几个数据,然后找到规律的。

对于$s_i$,我们分情况讨论:

首先,如果有$s_i=s_{i+1}$,那么删除$s_i$和$s_{i+1}$结果一样,那么可以把连续相同字符压成一个,输出时从小到大输出就可以了。

然后,如果有$s_i>s_{i+1}$,那么删除$s_i$肯定比不删除$s_i$更优,所以$i$排在所有$k(>i)$的前面。

最后,如果有$s_i<s_{i+1}$,那么删除$s_i$肯定没有不删除$s_i$优,所以$i$排在所有$k(>i)$的后面。

我是用一次$dfs$解决的,只要到一个连续下降子序列(压缩后无相邻相等)的末尾就往下$dfs$在回溯时再输出当前位置,边界为到达$N$。

Code:

#include<cstdio>
int N,bg[1000003],cnt;//bg:begin,一个连续相同序列的开始
char s[1000003];
inline void dfs(int d)
{
    int t,m;
    for(t=d;s[bg[t]]>s[bg[t+1]];++t)
    {
        for(m=bg[t];m<bg[t+1];++m)
        {
            printf("%d ",m); } if(m==N+1)return; } dfs(t+1);//回溯后再输出当前位置 for(m=bg[t];m<bg[t+1];++m) { printf("%d ",m); } } int main() { scanf(" %d %s",&N,s+1); for(int i=1;i<=N;++i) { if(s[i]==s[i-1])continue; bg[++cnt]=i;//压缩  } bg[++cnt]=N+1; dfs(1); return 0; }

猜你喜欢

转载自www.cnblogs.com/VexalwigGoodwcoffin/p/11368275.html
今日推荐