zoukankan      html  css  js  c++  java
  • Codeforces Round #584 E2. Rotate Columns (hard version)

    链接:

    https://codeforces.com/contest/1209/problem/E2

    题意:

    This is a harder version of the problem. The difference is only in constraints.

    You are given a rectangular n×m matrix a. In one move you can choose any column and cyclically shift elements in this column. You can perform this operation as many times as you want (possibly zero). You can perform this operation to a column multiple times.

    After you are done with cyclical shifts, you compute for every row the maximal value in it. Suppose that for i-th row it is equal ri. What is the maximal possible value of r1+r2+…+rn?

    思路:

    考虑状压DP, Dp[i][j], 表示已经对i列操作, 同时行状态为j的最大值.
    枚举每列, 枚举每列的选行状态, 跟之前不冲突的状态比较.
    枚举结束后转移状态,同时考虑可以选列最大值最大的n个列, 减少范围.
    DP还是难啊

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    int Dp[(1<<12)+10], Tmp1[(1<<12)+10], Tmp2[(1<<12)+10];
    int a[20][2010], Id[2010], Val[2010];
    int n, m;
    
    bool Cmp(int l, int r)
    {
        if (Val[l] > Val[r])
            return true;
        return false;
    }
    
    int main()
    {
        int t;
        scanf("%d", &t);
        while (t--)
        {
            memset(Val, 0, sizeof(Val));
            scanf("%d%d", &n, &m);
            for (int i = 0; i < n; i++)
            {
                for (int j = 1; j <= m; j++)
                {
                    scanf("%d", &a[i][j]);
                    Id[j] = j;
                    Val[j] = max(Val[j], a[i][j]);
                }
            }
            sort(Id + 1, Id + 1 + m, Cmp);
            m = min(n, m);
            memset(Dp, 0, sizeof(Dp));
            for (int i = 1; i <= m; i++)
            {
                memcpy(Tmp2, Dp, sizeof(Dp));
                memset(Tmp1, 0, sizeof(Tmp1));
                for (int ti = 0; ti < n; ti++)
                {
                    for (int s = 0; s < (1 << n); s++)
                        Tmp2[s] = Dp[s];
                    for (int s = 0; s < (1 << n); s++)
                    {
                        for (int li = 0; li < n; li++)
                        {
                            if (!((1 << li) & s))
                                Tmp2[s | (1 << li)] = max(Tmp2[s | (1 << li)], Tmp2[s] + a[(ti + li) % n][Id[i]]);
                        }
                    }
                    for (int s = 0; s < (1 << n); s++)
                        Tmp1[s] = max(Tmp1[s], Tmp2[s]);
                }
    //            for (int s = 0;s < (1 << n); s++)
    //                cout << Tmp1[s] << ' ' ;
    //            cout << endl;
                for (int s = 0;s < (1 << n); s++)
                    Dp[s] = Tmp1[s];
            }
            printf("%d
    ", Dp[(1<<n)-1]);
        }
    
        return 0;
    }
    
  • 相关阅读:
    opencv掩模操作
    cvtColor()学习
    opencv中mat类介绍
    c++中的stl
    opencv3中SurfFeatureDetector、SurfDescriptorExtractor、BruteForceMatcher的使用
    CUDA学习
    visual studio + opencv + contrib
    11.14/11.15 Apache和PHP结合 11.16/11.17 Apache默认虚拟主机
    11.10/11.11/11.12 安装PHP5 11.13 安装PHP7
    11.6 MariaDB安装 11.7/11.8/11.9 Apache安装
  • 原文地址:https://www.cnblogs.com/YDDDD/p/11645396.html
Copyright © 2011-2022 走看看