• topcoder srm 694 div1 -3


    1、给出$n$个数字,将其分成三个非空的组,每组的权值为该组所有数字的抑或。选择一种分法使得三组的权值和最大?

    思路:记录前两组的权值且三组有没有数字时第三组的值。(当前两组的值知道时第三组的权值是确定的,因为三组的抑或值是确定的)

    #include <iostream>
    #include <stdio.h>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    #include <string.h>
    #include <set>
    #include <vector>
    #include <time.h>
    #include <queue>
    #include <stack>
    #include <map>
    #include <assert.h>
    using namespace std;
    
    
    
    int f[2][256][256][8];
    
    
    class TrySail
    {
    public:
        int get(vector<int> A)
        {
            int pre=0,cur=1;
            memset(f[pre],-1,sizeof(f[pre]));
            f[0][0][0][0]=0;
            for(int i=0;i<(int)A.size();++i)
            {
                memset(f[cur],-1,sizeof(f[cur]));
                const int w=A[i];
                for(int b=0;b<256;++b) {
                    for(int c=0;c<256;++c) {
                        for(int d=0;d<8;++d) {
                            int k=f[pre][b][c][d];
                            if(k==-1) continue;
                            f[cur][b^w][c][d|4]=k;
                            f[cur][b][c^w][d|2]=k;
                            f[cur][b][c][d|1]=k^w;
                        }
                    }
                }
                pre^=1;
                cur^=1;
            }
            int ans=0;
            for(int a=0;a<256;++a) {
                for(int b=0;b<256;++b) {
                    if(f[pre][a][b][7]!=-1) {
                        ans=max(ans,f[pre][a][b][7]+a+b);
                    }
                }
            }
            return ans;
        }
    };
    

      

    2、给出$n*m$的只包含'A'到'Z'的字符矩阵。对于一个列的集合$S$,如果任意两行$i,j$在$S$上不完全相同,称$S$可以区分所有行。问有多少种列的子集可以区分所有行?$nleq 1000,mleq 20$

    思路:首先,找到哪些列的子集不能区分所有行。令$f[s]=1$表示集合$s$不能区分所有行,那么所有的$s$^$2^{k}$都不能区分。其中$k$满足$s$&$2^{k} eq 0$。

    #include <iostream>
    #include <stdio.h>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    #include <string.h>
    #include <set>
    #include <vector>
    #include <time.h>
    #include <queue>
    #include <stack>
    #include <map>
    #include <assert.h>
    using namespace std;
    
    
    int f[1<<20];
    
    class DistinguishableSetDiv1
    {
    
    public:
        int count(vector<string> A)
        {
    
            int n=A.size();
            int m=A[0].size();
    
            memset(f,0,sizeof(f));
            for(int i=0;i<n;++i) for(int j=i+1;j<n;++j)
            {
                int s=0;
                for(int k=0;k<m;++k) if(A[i][k]==A[j][k]) s|=1<<k;
                f[s]=1;
            }
            int ans=0;
            for(int i=(1<<m)-1;i>=0;--i)
            {
                if(f[i])
                {
                    for(int k=0;k<m;++k) if(i&(1<<k)) f[i^(1<<k)]=1;
                }
                else ++ans;
            }
            return ans;
        }
    };
    

      

  • 相关阅读:
    你的背包,被我找到了(01背包问题)
    一点微小的改动,让你从B树理解到B+树
    有哪些令人拍案叫绝的算法?
    来来来,今天教你们用 CV 算法整点好玩的...
    内存都没了,还能运行程序?
    我的常用软件大公开!
    漫画:美团面试题(整数拆分)
    科普:我就想写个爬虫,到底要学多少东西啊?
    腾讯和阿里在 B 站评论区相遇了!
    程序员注意:这个群可以学英语,还全程免费!
  • 原文地址:https://www.cnblogs.com/jianglangcaijin/p/6888352.html
Copyright © 2020-2023  润新知