• Codeforces 543C Remembering Strings(DP)


    题意比较麻烦

    见题目链接


    Solution:

       非常值得注意的一点是题目给出的范围只有20,而众所周知字母表里有26个字母。于是显然对一个字母进行变换后是不影响到其它字符串的。

             20的范围恰好又是常见状压DP的范围,所有状态压缩后用DP[sta]代表对应位的字符串已经满足要求的最小花费。

             转移的时候,对一个字符串,逐列判断使它满足条件的最小花费,记录使用这个策略对sta的影响。

             即对同一列有两种情况,直接变换该字符串的这一位,或者变换这一列的sum-1个有相同字符的位置(去掉代价最大的)。

    #include <bits/stdc++.h>
    using namespace std;
    
    int dp[1 << 20];
    int cost[30][30], f[30][30], change[30][30];
    
    int n, m;
    char s[30][30];
    
    inline void getCost ()
    {
        for (int k = 0; k < n; ++k)
        {
            for (int i = 0; i < m; ++i)
            {
                int sum = 0, tem = 0;
                f[i][k] = 0x7fffffff;
                for (int j = 0; j < n; ++j)
                {
                    if (s[j][i] == s[k][i])
                    {
                        change[i][k] |= 1 << j;
                        sum += cost[j][i];
                        tem = max (tem, cost[j][i]);
                    }
                }
                f[i][k] = min (f[i][k], sum - tem);
            }
        }
    }
    
    int main()
    {
        ios::sync_with_stdio (0);
    
        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 >> cost[i][j];
    
        getCost();
    
        memset (dp, 0x3f, sizeof dp);
        dp[0] = 0;
        for (int st = 0; st < (1 << n); ++st)
        {
            for (int i = 0; i < n; ++i)
            {
                if ( (st & 1 << i) == 0)
                {
                    for (int j = 0; j < m; ++j)
                    {
                        dp[st | change[j][i]] = min (dp[st | change[j][i]], dp[st] + f[j][i]);
                        dp[st | 1 << i] = min (dp[st | 1 << i], dp[st] + cost[i][j]);
                    }
                    break;
                }
            }
        }
        cout << dp[ (1 << n) - 1] << endl;
    }
    View Code
  • 相关阅读:
    GO 锁
    GO worker pool
    GO sync.Once
    GO channel
    Go sync.Map
    GO select
    GO atomic包
    GO sync.WaitGroup
    ActivatorUtilities.CreateInstance用于各种激活器服务的帮助程序代码。
    IQueryable简单分页的扩展方法
  • 原文地址:https://www.cnblogs.com/keam37/p/4515538.html
Copyright © 2020-2023  润新知