HDU6103 Kirinriki 题解报告

题目传送门

【题目大意】

在给定的字符串序列中,找出两个不重的相同长度的子序列使得差异值不大于$m$,求满足条件的最长子序列的长度,其中两个长度为$n$的字符串$A,B$的差异值$dis=\sum_{i=1}^{n}|A_i-B_{n-i}|$。

【思路分析】

由于两个子序列长度相同,所以我们可以把它们看作是对称的,我们考虑枚举中间的对称轴,对称轴可能是序列中的一个位置,也可能是两个相邻位置之间的空隙。

一边枚举一边记录答案,最后枚举完所有的可能即可得出最大值。

【代码实现】

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #define g() getchar()
 7 #define rg register
 8 #define go(i,a,b) for(rg int i=a;i<=b;i++)
 9 #define back(i,a,b) for(rg int i=a;i>=b;i--)
10 #define db double
11 #define ll long long
12 #define il inline
13 #define pf printf
14 using namespace std;
15 int fr(){
16     int w=0,q=1;
17     char ch=g();
18     while(ch<'0'||ch>'9'){
19         if(ch=='-') q=-1;
20         ch=g();
21     }
22     while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=g();
23     return w*q;
24 }
25 const int N=5002;
26 int T,m,len,ans;
27 char s[N];
28 int main(){
29     //freopen("","r",stdin);
30     //freopen("","w",stdout);
31     T=fr();
32     while(T--){
33         m=fr();
34         scanf("%s",s);
35         len=strlen(s);ans=0;
36         go(i,1,len-1){//对称轴为序列中的一个位置
37             rg int l1=i-1,r1=l1;
38             rg int l2=i+1,r2=l2;
39             rg int sum=0;
40             while(l1>=0&&l2<len){
41                 sum+=abs(s[l1]-s[l2]);
42                 while(sum>m) sum-=abs(s[r1--]-s[r2++]);
43                 ans=max(ans,r1-l1+1);
44                 l1--;l2++;
45             }
46         }
47         go(i,0,len-1){//对称轴为序列中两个相邻位置之间的空隙
48             rg int l1=i,r1=l1;
49             rg int l2=i+1,r2=l2;
50             rg int sum=0;
51             while(l1>=0&&l2<len){
52                 sum+=abs(s[l1]-s[l2]);
53                 while(sum>m) sum-=abs(s[r1--]-s[r2++]);
54                 ans=max(ans,r1-l1+1);
55                 l1--;l2++;
56             }
57         }
58         pf("%d\n",ans);
59     }
60     return 0;
61 }
代码戳这里

转载于:https://www.cnblogs.com/THWZF/p/11392441.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值