**题目链接:**https://uoj.ac/problem/519 **题目背景:**美团杯的签到题,蒟蒻的我不会做QAQ。。。 题目大意: 解题思路: 2.s1[i]不是’xxxll’的第l+1个元素(直接转移,不用修改) 完整AC代码:
给定一个字符串s,只含有字符‘x’和‘l’,你可以将’x’变成’l’,也可以‘l’变成’x’,问你字符串删去任意个字符都不会出现子串’xxxll’,至少需要变换几次。
小数据:n<=10,暴力枚举即可。
大数据:n<=100,比赛的时候想的是贪心,但是‘x’变‘l’会对之前的串产生影响,’l’变‘x’会对之后的串产生影响。所以并不能把问题的最优解转化为子问题的最优解,贪心是不行的。贪心不行的话,就可以想到动态规划了。
我们可以先看有哪几种串是满足条件的
1.空串。前缀是0。
2.‘x’,‘xl’,‘xll’…。前缀是1。
3.‘xx’,‘xlx’,‘xxll’…。前缀是2。
4.‘xxx’,‘xxlx’,‘xlxx’…。前缀是3。
5.‘xxxl’,‘xxlxl’,‘xlxxl’…。前缀是4。
只有以上情况是满足条件的。
那么我们可以设dp方程为dp[i][l],即只修改前i个元素,使前缀为l,最少需要多少次。
那么答案就是dp[n][0]~dp[n][4]中最小的那个。
那么dp的转移方程是什么呢。
分成两种情况
1.s1[i]是’xxxll’的第l+1个元素dp[i+1][j+1]=min(dp[i+1][j+1],dp[i][j]);//不修改前缀+1 dp[i+1][j]=min(dp[i+1][j],dp[i][j]+1);//修改次数+1
dp[i+1][j]=min(dp[i+1][j],dp[i][j]);
#include <iostream> #include <stdio.h> #include <cstring> using namespace std; const int maxn=105; const int inf=10000; int T; char s1[maxn],s2[maxn]; int dp[maxn][6]; int main() { scanf("%d",&T); s2[1]='x',s2[2]='x',s2[3]='x',s2[4]='l',s2[5]='l'; while(T--) { scanf("%s",s1); memset(dp,inf,sizeof(dp)); int n=strlen(s1); dp[0][0]=0; for(int i=0;i<n;i++) for(int j=0;j<5;j++) { if(dp[i][j]<inf) { if(s2[j+1]==s1[i]) { dp[i+1][j+1]=min(dp[i+1][j+1],dp[i][j]); dp[i+1][j]=min(dp[i+1][j],dp[i][j]+1); } else dp[i+1][j]=min(dp[i+1][j],dp[i][j]); } } int ans=inf; for(int i=0;i<5;i++) ans=min(ans,dp[n][i]); printf("%dn",ans); } return 0; }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算