zoukankan      html  css  js  c++  java
  • 【51NOD1447】好记的字符串

    题面

    现在有n个长度一样的字符串,我们说这些字符串是好记的当且仅当,每一个字符串存在一个位置i,其它字符串在i位置的字符和它不一样。
    例如{"abc", "aba", "adc", "ada"}这些字符串是不好记的。
    而{"abc", "ada", "ssa"}这些是好记的:

    对于第一串,在第3个位置,只有它有c;

    对于第二个串,在第2个位置,只有它有d;

    对于第三个串,在第2个位置,只有它有s;

    现在给你n个字符串,你要做一些小的修改使得他们好记。修改第i个字符串的第j个位置要花费aij。那么想要这些字符串都好记,最少的花费是多少呢?
    样例解释:把第一列的前三个a改成b,c,d。
    n, m (1 ≤ n, m ≤ 20),表示有n个字符串,他们的长度都是m。
    ai1, ai2, ..., aim (0 ≤ aij ≤ 10^6)。

    分析

    至少存在一个位置所有的字母都不同才行,那就枚举每个位置,求出使这一位上的字母完全不同的最大值,然后字母间的冲突用二进制来处理。
    挂了...
    放弃挣扎,啃题解,状压不是我等蒟蒻能轻易学得炉火纯青的啊...
    还有一个隐藏条件,n<=20,说明你找到相同的字母,一定有存在的改法使这个位置不冲突。因为字母有26个啊。所以可以放心地随便改了。
    1.将这个位置上有这个重复字母的串全部修改。让这些串都好记。
    2.只修改这一个串,使这一个串好记。
    对于修改1,需要额外维护位置j的字母i的位置在哪些地方 用01串存,还需要维护修改这些字母的总花费和最大花费,我们就不修改花费最大的那个串。
    f[i]存一个数,其二进制形式的每一位k表示第k+1个串是否好记了。每次取出状态中的不好记的串尝试对它分别进行两种修改即可转移。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define N 28
    int k,n,m,mx,tmp,notused=1234567890;
    int f[1<<21],a[N][N],maxx[N][N],sum[N][N],mp[N][N];
    char s[N][N];
    int main()
    {
        scanf("%d%d",&n,&m);
        mx=(1<<n)-1;
        for(int i=1;i<=n;i++)scanf("%s",s[i]+1);
        for(int i=1;i<=mx;i++)f[i]=notused;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                scanf("%d",&a[i][j]);
                sum[j][s[i][j]-'a']+=a[i][j];
                maxx[j][s[i][j]-'a']=max(maxx[j][s[i][j]-'a'],a[i][j]);
                mp[j][s[i][j]-'a']+=(1<<(i-1));
            }    
        for(int i=0;i<=mx;i++)
        {
            if(f[i]==notused)continue;
            for(int j=0;j<n;j++)if((i&(1<<j))==0){k=j+1;break;}
            for(int j=1;j<=m;j++)
            {
                f[i|(1<<k-1)]=min(f[i|(1<<k-1)],f[i]+a[k][j]);
                tmp=f[i]+sum[j][s[k][j]-'a']-maxx[j][s[k][j]-'a'];
                f[i|mp[j][s[k][j]-'a']]=min(f[i|mp[j][s[k][j]-'a']],tmp);
            }
        }
        printf("%d
    ",f[mx]);
    }

    送一组debug时花10积分下的小数据

    input
    5 2
    aa
    aa
    ab
    bb
    bb
    1 100
    100 100
    1 1
    100 100
    100 1
    output
    4
    “Make my parents proud,and impress the girl I like.”
  • 相关阅读:
    用于表示socket的结构体
    Parcelable与Serializable接口的用法和区别
    java类初始化顺序
    孙卫琴java面向对象编程学习笔记
    linux档案权限
    js弹出模态与非模态页面
    ubuntu开启默认的root用户
    java开发实战学习笔记1
    JQuery ajax回调函数
    hadoop命令
  • 原文地址:https://www.cnblogs.com/NSD-email0820/p/9789795.html
Copyright © 2011-2022 走看看