zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Asp.Net Web API 2第八课——Web API 2中的属性路由
    Asp.Net Web API 2第七课——Web API异常处理
    Asp.Net Web API 2第六课——Web API路由和动作选择
    Asp.Net Web API 2第五课——Web API路由
    开始学习python
    BMI 小程序 购物车
    深浅copy 文件操作
    字典 dict 集合set
    基本数据类型 (str,int,bool,tuple,)
    python 运算符
  • 原文地址:https://www.cnblogs.com/keam37/p/4515538.html
Copyright © 2011-2022 走看看