LA 4394 String painter

本文详细介绍了一种区间动态规划问题的解决方法,通过实例讲解如何求解字符串转换的最少步骤问题,给出了状态定义、状态转移方程及完整的代码实现。

1.题目描述:点击打开链接

2.解题思路:本题是区间dp类的问题,根据题意描述,要求我们把给定的A串变成B串,每次操作时候可以选一段区间,然后将这个区间都刷成同一个字符,询问最少需要多少步。因为A串和B串部分位置可能相同,为了便于分析,让我们先忘掉A串,从一个空串考虑起。

按照以往的经验,我们可以设dp(i,j)表示把字符串A中的i...j变成字符串B中的i...j需要的最少步数。多次尝试后可以发现,如果我们刷同一个字符串,一定是希望刷的越长越好。根据题意不难得知长区间的结果依赖于短区间,那么不难得到如下的状态转移方程:

dp(i,j)=dp(i+1,j)+1; 

dp(i,j)=min{dp(i+1,k)+dp(k+1,j)}; (b[i]==b[k])

第一个方程表示单刷第i位的字符。第二个方程表示如果b[i]==b[k]时候,那么刷第k位的时候也可以同时刷第i位,因此只需要dp(i+1,k)即可表示dp(i,k)的结果了。由于长区间依赖短区间的结果,那么可以实现从小到大枚举尾部,然后再从大到小枚举头部。这样,每次需要的区间一定是之前计算过的。

计算出dp数组,还并没有得到答案。因为dp表示的是A串和B串完全不同时候,最少需要几步。接下来考虑利用dp数组和A数组来得到最终的结果。此时可以用ans[i]表示字符串A中0..i变成字符串B的0..i所需的最小步数。那么当A[i]==B[i]时候,ans[i]=ans[i-1],否则,则遍历0..i之间的所有分法。即ans[i]=min{ans[k],dp(k+1,i)}。这样,最后的答案就是ans[len-1]。

3,.代码:

#include<iostream>
#include<algorithm>
#include<cassert>
#include<string>
#include<sstream>
#include<set>
#include<bitset>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cctype>
#include<list>
#include<complex>
#include<functional>
using namespace std;

#define me(s) memset(s,0,sizeof(s))
#define rep(i,n) for(int i=0;i<(n);i++)
#define pb push_back
typedef long long ll;
typedef pair <int,int> P;


const int N=100+10;

char s1[N],s2[N];

int dp[N][N];
int ans[N];

int main()
{
    while(~scanf("%s%s",s1,s2))
    {
        int len=strlen(s1);
        me(dp);
        for(int j=0;j<len;j++)//j是尾部
            for(int i=j;i>=0;i--)//i是头部
        {
            dp[i][j]=dp[i+1][j]+1; //单刷第i位
            for(int k=i+1;k<=j;k++)
                if(s2[i]==s2[k]) //如果相等,说明i,k两位可以同时刷,更新答案
                dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]);
        }
        for(int i=0;i<len;i++)
            ans[i]=dp[0][i];
        for(int i=0;i<len;i++)
            if(s1[i]==s2[i]) ans[i]=ans[i-1];//相等,那么第i位不需要改动
            else for(int j=0;j<i;j++) //否则,分成2段考虑
                ans[i]=min(ans[i],ans[j]+dp[j+1][i]);
        printf("%d\n",ans[len-1]);
    }
}


package com.example.myapplication import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.example.myapplication.ui.theme.MyApplicationTheme class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { MyApplicationTheme { Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { GreetingImage(message = "Happy Birthday Sam!", from = "From Emma") title("Jetpack Compose tutorial") } } } } } @Composable fun GreetingImage(message: String = "1", from: String = "2", modifier: Modifier = Modifier) { val img = painterResource(R.drawable.pic) Box(modifier = modifier) { Image( painter = img, contentDescription = "", ) GreetingText( message, from ) } } @Composable fun title(message: String, modifier: Modifier = Modifier) { Box(modifier = modifier.padding(16.dp)) { Text( fontSize = 36.sp, text = message, ) } } @Composable fun GreetingText(message: String, from: String, modifier: Modifier = Modifier) { Column( modifier = Modifier .padding(8.dp) ) { Text( text = message, textAlign = TextAlign.Center ) Text( text = from, modifier = Modifier .padding(16.dp) .align(alignment = Alignment.End) ) } } @Preview(showBackground = true, showSystemUi = true, name = "la la la") @Composable fun BirthdayCardPreview() { MyApplicationTheme { GreetingText("Android", "cccc") } } 我希望title可以在 GreetingImage的下面,给出代码实现
08-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值