String painter (区间dp+简单dp)

本文介绍了一种算法,用于解决将一个字符串通过一系列操作转换为另一个字符串的问题,目的是找到完成转换所需的最少操作次数。
There are two strings A and B with equal length. Both strings are made up of lower case letters.
Now you have a powerful string painter. With the help of the painter, you can change a segment of
characters of a string to any other character you want. That is, after using the painter, the segment is
made up of only one kind of character. Now your task is to change A to B using string painter. What’s
the minimum number of operations?
Input
Input contains multiple cases. Each case consists of two lines:
• The first line contains string A.
• The second line contains string B.
The length of both strings will not be greater than 100.
Output
A single line contains one integer representing the answer.
Sample Input
zzzzzfzzzzz
abcdefedcba
abababababab
cdcdcdcdcdcd
Sample Output
6

7

题目大概:

有第一个串,变成第二个串,需要最少多少步操作,每次操作可以把一个任意区间涂成一样的颜色。

思路:

如果直接dp一下,那么会有在两种转移方式,当第一个串的第i个和第二个串的第i个,sum【i】=sum【i-1】.这个比较简单。

但是如果不相等那,如果是sum【i】=sum【i-1】+1;那显然是错误的,如果,刷第i段的时候,可以和前面的某一部分一起刷,那么就会多算一次。

那么怎么算那,可以直接暴力枚举一下,sum【i】=min(sum【i】,sum【j】+dp【j+1】【i】)j 属于(0--i)

这样每次不相等,都从前面枚举一遍。这也是一种套路题,很多题都是这么做。但这道题的最佳dp【j+1】【i】没有给出来。也没有从前面得到。所以只能自己算一下,由空白串到第二个串的最佳刷的次数是多少,用一个区间dp求一下,每到遇到两个相同的颜色,就可以优化一下,一起刷。一直优化到最后。

代码:

#include <bits/stdc++.h>

using namespace std;
const int maxn=110;
const int INF=0x3f3f3f3f;
char a[maxn];
char b[maxn];
int dp[maxn][maxn];
int sum[maxn];
int main()
{
    while(~scanf("%s%s",a,b))
    {
        memset(dp,0,sizeof(dp));
        memset(sum,0,sizeof(sum));
        int n=strlen(a);
        //for(int i=0;i<n;i++)dp[i][i]=1;
        for(int i=1;i<=n;i++)
        {
            for(int l=0;l<n-i+1;l++)
            {
                int r=l+i-1;
                dp[l][r]=dp[l+1][r]+1;
                for(int k=l+1;k<=r;k++)
                {
                    if(b[l]==b[k])
                    dp[l][r]=min(dp[l+1][k]+dp[k+1][r],dp[l][r]);
                }
            }
        }

        for(int i=0;i<n;i++)
        {
            sum[i]=dp[0][i];
        }
        for(int i=0;i<n;i++)
        {
            if(a[i]==b[i])
            {
                sum[i]=sum[i-1];
            }
            else
            {
                for(int j=0;j<=i;j++)
                {
                    sum[i]=min(sum[j]+dp[j+1][i],sum[i]);
                }
            }
        }
        printf("%d\n",sum[n-1]);
    }
    return 0;
}


为什么图片不显示:package com.example.carseting.View import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.SegmentedButtonColors import androidx.compose.material3.SegmentedButtonDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.example.carseting.R import com.example.carseting.Model.SegmentedOption @Composable fun CommonOperationScreen() { val shape = RoundedCornerShape(5.dp) val colors= ButtonDefaults.buttonColors( containerColor = Color(0xFFE0E0F0), // 背景颜色 contentColor = Color.Black // 黑色文字/图标 )// 默认背景色 // 分项选择button的样式 val colors2 = SegmentedButtonDefaults.colors() val options = listOf<SegmentedOption>( SegmentedOption( key = "OFF", selected_icon = painterResource(R.drawable.carsetting_icon_off_s), unselected_icon = painterResource(R.drawable.carsetting_icon_off_n), text = "OFF" ), SegmentedOption( key = "AUTO", unselected_icon = painterResource(R.drawable.carsetting_icon_auto_n), selected_icon = painterResource(R.drawable.carsetting_icon_auto_s), text = "AUTO" ), SegmentedOption( key = "POSITON", unselected_icon = painterResource(R.drawable.carsetting_icon_position), selected_icon = painterResource(R.drawable.carsetting_icon_position_s), text = "POSITON" ), SegmentedOption( key = "LOW_BEAM", unselected_icon = painterResource(R.drawable.carsetting_icon_low_beam), selected_icon = painterResource(R.drawable.carsetting_icon_low_beam_s), text = "LOW_BEAM" ) ) Column( modifier = Modifier.fillMaxSize() ) { Column( modifier = Modifier.weight(1f).verticalScroll(rememberScrollState()), // 垂直滚动,用weight(1f)限制滚动组件的高度 verticalArrangement = Arrangement.Center, // 垂直平均分布,居中对齐 horizontalAlignment = Alignment.CenterHorizontally ) { Image( painter = painterResource(id = R.drawable.carsetting_pic_car02), contentDescription = "这是一张车辆图片", // 必须有这句,否则会报错,这是无障碍提示语 modifier = Modifier.width(260.dp) ) Row ( modifier = Modifier.fillMaxWidth().padding(1.dp), horizontalArrangement = Arrangement.Center, // 垂直平均分布,居中对齐 verticalAlignment = Alignment.CenterVertically ){ ButtonShape( shape = shape, colors = colors, width = 80.dp, height = 60.dp, id = R.drawable.carsetting_icon_hbx_n, start = 0.dp, end = 0.dp, fontSize = 10.sp, contentDescription = "这是后备箱的按钮", text = "后备箱", onClick = {} ) Spacer(modifier = Modifier.width(5.dp)) ButtonShape( shape = shape, colors = colors, width = 80.dp, height = 60.dp, start = 5.dp, end = 5.dp, id = R.drawable.carsetting_icon_cdk_n, fontSize = 10.sp, contentDescription = "这是充电口的按钮", text = "充电口", onClick = {} ) Spacer(modifier = Modifier.width(5.dp)) ButtonShape( shape = shape, colors = colors, width = 100.dp, height = 60.dp, start = 15.dp, end = 15.dp, id = R.drawable.carsetting_icon_left_ccs_n, fontSize = 10.sp, contentDescription = "这是左后窗锁止的按钮", text = "左后窗锁止", onClick = {} ) } Row( modifier = Modifier.fillMaxWidth().padding(16.dp), horizontalArrangement = Arrangement.Center, // 垂直平均分布,居中对齐 verticalAlignment = Alignment.CenterVertically ) { ButtonShape( shape = shape, colors = colors, width = 100.dp, height = 60.dp, start = 15.dp, end = 15.dp, id = R.drawable.carsetting_icon_right_ccs_n, fontSize = 10.sp, contentDescription = "这是右后窗锁止的按钮", text = "右后窗锁止", onClick = {} ) Spacer(modifier = Modifier.width(5.dp)) ButtonShape( shape = shape, colors = colors, width = 100.dp, height = 60.dp, start = 15.dp, end = 15.dp, id = R.drawable.carsetting_icon_hsjtj_n, fontSize = 10.sp, contentDescription = "这是后视镜调节的按钮", text = "后视镜调节", onClick = {} ) } Row ( modifier = Modifier.fillMaxWidth().padding(16.dp), horizontalArrangement = Arrangement.Center, // 垂直平均分布,居中对齐 verticalAlignment = Alignment.CenterVertically ){ ButtonShape( shape = shape, colors = colors, width = 100.dp, height = 60.dp, start = 15.dp, end = 15.dp, id = R.drawable.carsetting_icon_hsj_n, fontSize = 10.sp, contentDescription = "这是后视镜折叠的按钮", text = "后视镜折叠", onClick = {} ) Spacer(modifier = Modifier.width(5.dp)) ButtonShape( shape = shape, colors = colors, width = 80.dp, height = 60.dp, start = 5.dp, end = 5.dp, id = R.drawable.carsetting_icon_zdy_n, fontSize = 10.sp, contentDescription = "这是自定义按钮", text = "自定义", onClick = {} ) } // 大灯控制 SegmentSelectionButton( options = options, initialSelectedKey = "OFF", onOptionSelected = {}, shape = RoundedCornerShape(5.dp), colors = colors2, text = "大灯控制", fontSize = 20.sp, start = 2.dp, end = 100.dp, iconSize = 18.dp, ) } } } @Preview @Composable fun CommonOperationScreenPreview(){ CommonOperationScreen() } package com.example.carseting.View import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material3.Icon import androidx.compose.material3.SegmentedButton import androidx.compose.material3.SegmentedButtonColors import androidx.compose.material3.SegmentedButtonDefaults import androidx.compose.material3.SingleChoiceSegmentedButtonRow import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Shape import androidx.compose.ui.layout.ModifierLocalBeyondBoundsLayout import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp import com.example.carseting.Model.SegmentedOption @Composable fun SegmentSelectionButton( options: List<SegmentedOption>, // 分段选项列表 initialSelectedKey: String = options.firstOrNull()?.key?:"", // 初始化选中项 onOptionSelected: (SegmentedOption) -> Unit, // 选中项变化回调 shape: Shape, // 按钮形状 colors: SegmentedButtonColors = SegmentedButtonDefaults.colors(), text: String, fontSize: TextUnit, start: Dp, end: Dp, iconSize: Dp ){ var selectedKey by remember { mutableStateOf(initialSelectedKey) } Column( modifier = Modifier.fillMaxSize() ) { Text( text = text, fontSize = fontSize, modifier = Modifier.padding(start = start, end = end, bottom = 5.dp) ) SingleChoiceSegmentedButtonRow ( modifier = Modifier.padding(1.dp) ) { options.forEach { option -> val isSelected = selectedKey == option.key SegmentedButton( selected = isSelected, onClick = { selectedKey = option.key onOptionSelected(option) }, shape = shape, //colors = colors, icon = { SegmentedButtonDefaults.Icon( active = selectedKey == option.key, // 表示当前索引下的按钮是否选中状态,影响的是显示的图标样式 activeContent = { // 设置选中时的图标,这里设置的就是带圆形的✓。 option.selected_icon?.let { Icon( painter = it, contentDescription = "", modifier = Modifier.fillMaxSize() ) } }, inactiveContent = { // 设置未选中时的图标,这里设置的就是带圆形的✓。 option.unselected_icon?.let { Icon( painter = it, contentDescription = "", modifier = Modifier.fillMaxSize() ) } } ) } ) { } } } } } package com.example.carseting.Model import androidx.compose.ui.graphics.painter.Painter data class SegmentedOption( val key: String, // 选择项唯一标识 val selected_icon: Painter?, // 图标资源 val unselected_icon: Painter?, // 图标资源 val text: String, // 文字内容 )
最新发布
08-14
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值