字母交换
字母交换
题目描述
【编码题】字符串S由小写字母构成,长度为n。定义一种操作,每次都可以挑选字符串中任意的两个相邻字母进行交换。询问在至多交换m次之后,字符串中最多有多少个连续的位置上的字母相同?
输入描述:
第一行为一个字符串S与一个非负整数m。(1 <= |S| <= 1000, 1 <= m <= 1000000)
输出描述:
一个非负整数,表示操作之后,连续最长的相同字母数量。
示例1
输入
abcbaa 2
输出
2
说明
使2个字母a连续出现,至少需要3次操作。即把第1个位w置上的a移动到第4个位置。
所以在至多操作2次的情况下,最多只能使2个b或2个a连续出现。
思路:
动态规划递推公式 dp【i】[j]= dp【i+1】【j-1】 + a[j]-a[i] -(j-i);,计算时只算上三角情况,每个字母单独计算,递归公式看懂就会做了。第一轮计算相邻相同字母的相邻距离,第二轮计算相差两个位置的字母靠近需要多少距离
上三角举例
0111
0011
0001
代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int max(int a,int b){
return a>b?a:b;
}
int main(){
char s[10001];
int m,max_seq;
scanf("%s%d",s,&m);
int size_s = strlen(s);
for(char c ='a';c<='z' ; c++){
int *a = (int *)malloc(sizeof(int)*10002);
int size =0;
for(int i=0;i<size_s;i++){
//把相同字符的位置求出来
if(s[i] ==c) a[size++] = i;
}
if(size){
int dp[1002][1001];
memset(dp,0,sizeof(dp));
int seq = 1;
//只计算上三角情况
for(int r=1;r<size;r++){
for(int i=0;i<size-r;i++){
int j = i+r;
// 在第一轮的情况下
if(j==i+1){
dp[i][j] = a[j]-a[i]-1;
}else{
dp[i][j] = dp[i+1][j-1] + a[j]-a[i] -(j-i);
}
if(dp[i][j]<=m)
seq = max(seq,j-i+1);
}
}
max_seq = max(max_seq,seq);
}
}
printf("%d\n",max_seq);
}
代码效率:
运行时间:11ms, 超过57.14%用C提交的代码
占用内存:4348KB, 超过40.00%用C提交的代码
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!