Codeforces 543C Remembering Strings 题解

本文介绍了一种使用状态压缩动态规划解决特定字符串优化问题的方法。问题要求将一组等长字符串通过更改字符使其变得“好记”,即每个字符串至少有一位字符在所有字符串的对应位置上是唯一的。文章详细阐述了解决方案的实现思路与核心代码,通过状态压缩来记录字符串的好记状态,并采用动态规划找到达到目标所需的最小成本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意
给定一些等长的仅有小写字母组成的字符串,要求把每一个字符串变为好记的,定义为存在它的某一位字符在所有字符串中那一位独特,给定变换某个字符串某一位的代价,不限制把它转换成什么小写字母,问达到要求的最少的代价是多少
思路
状态压缩dp,用二进制表示字符串是否好记,1表示好记,0表示不好记,dp值表示到当前状态的最少代价,每一次转移只需考虑最低的为0的一位,两种可能,一种是把它变出去,另一种是在跟它相同(包括自己)的里边仅保留最大的,把其它的都换走,这样可以转移到下一个状态了,对每一个状态不断地更新到最小值,最后全1的状态的值就是答案
代码
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define INF 1000000001
char s[21][21];
int a[21][21];
int dp[1<<20];
int main()
{
    int n,m,e,add,maxx,change;
    cin>>n>>m;
    for(int i=0;i<n;i++)
        cin>>s[i];
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            cin>>a[i][j];
    e=(1<<n);
    for(int i=1;i<e;i++)
        dp[i]=INF;
    for(int i=0;i<e;i++)
        for(int j=0;j<n;j++)
            if(!((i>>j)&1))
            {
                for(int k=0;k<m;k++)
                {
                    dp[i|(1<<j)]=min(dp[i|(1<<j)],dp[i]+a[j][k]);
                    add=0;
                    maxx=0;
                    change=0;
                    for(int l=0;l<n;l++)
                    {
                        if(s[j][k]==s[l][k])
                        {
                            add+=a[l][k];
                            maxx=max(maxx,a[l][k]);
                            change|=(1<<l);
                        }
                    }
                    dp[i|change]=min(dp[i|change],dp[i]+add-maxx);
                }
                break;
            }
    printf("%d\n",dp[e-1]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值