[atAGC054D]ox

发布时间:2022-07-04 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了[atAGC054D]ox脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

对于两个字符串$s$和$t$(保证其中每一种字符个数相同),定义$s$和$t$的相对逆序对数为$s$得到$t$的最少交换次数,显然同种字符相对顺序保持不变,因此即依次编号后的逆序对数

问题不妨看作构造合法字符串$t$使得$s$和$t$的相对逆序对数最小,定义$f_{S}(s)$为$s$仅保留$S$中的字符后所得到的字符串,那么有以下两个结论——

结论1:当$S={(,)}$时,若$t$是使得$s$和$t$相对逆序对数最小的合法字符串,则$f_{S}(t)$也是使得$f_{S}(s)$和$f_{S}(t)$相对逆序对数最小的合法字符串

结论2:当$S={o,x}$时,若$t$是使得$s$和$t$相对逆序对数最小的合法字符串,则$f_{S}(s)=f_{S}(t)$

由此,不妨先求出$S={(,)}$时的$f_{S}(t)$,进而即将$o$和$x$从左到右依次插入,显然这可以用一个二维dp计算,条件为$x$之前左括号数严格大于右括号数,计算答案考虑逆序对数即可

@R_733_1304@为$o(n^{2})$,可以通过

[atAGC054D]ox

[atAGC054D]ox

 1 #include<bITs/stdc++.h>
 2 using namespace std;
 3 #define N 8005
 4 queue<int>q;
 5 vector<int>vb,vc;
 6 int n,cnt,ans,sum[N],f[N][N];
 7 char s[N]; 
 8 int main(){
 9     scanf("%s",s+1);
10     n=strlen(s+1);
11     vb.push_back(0),vc.push_back(0);
12     for(int i=1;i<=n;i++){
13         if (s[i]=='('){
14             cnt++;
15             vb.push_back(i);
16             if (!q.empty()){
17                 vb.push_back(q.front());
18                 q.pop();
19             }
20         }
21         if (s[i]==')'){
22             cnt--;
23             if (cnt<0)q.push(i);
24             else vb.push_back(i);
25         }
26         if ((s[i]=='o')||(s[i]=='x'))vc.push_back(i);
27     }
28     for(int i=1;i<vb.size();i++){
29         sum[i]=sum[i-1];
30         if (s[vb[i]]=='(')sum[i]++;
31         else sum[i]--;
32     }
33     memset(f,0x3f,sizeof(f));
34     memset(f[0],0,sizeof(f[0]));
35     for(int i=1;i<vc.size();i++){
36         cnt=0;
37         for(int j=0;j<vb.size();j++)
38             if (vc[i]>vb[j])cnt++;
39         for(int j=0;j<vb.size();j++){
40             if (vc[i]<vb[j])cnt++;
41             else cnt--;
42             if ((s[vc[i]]=='o')||(sum[j]))f[i][j]=min(f[i][j],f[i-1][j]+cnt);
43         }
44         for(int j=1;j<vb.size();j++)f[i][j]=min(f[i][j],f[i][j-1]);
45     }
46     ans=0x3f3f3f3f;
47     for(int i=0;i<vb.size();i++)ans=min(ans,f[(int)vc.size()-1][i]);
48     for(int i=1;i<vb.size();i++)
49         for(int j=i+1;j<vb.size();j++)
50             if (vb[i]>vb[j])ans++;
51     PRintf("%dn",ans);
52     return 0;
53 } 
View Code

&nbsp;

脚本宝典总结

以上是脚本宝典为你收集整理的[atAGC054D]ox全部内容,希望文章能够帮你解决[atAGC054D]ox所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。