首页 > 其他分享 >2572. 无平方子集计数(状态压缩dp)

2572. 无平方子集计数(状态压缩dp)

时间:2023-02-25 10:24:08浏览次数:55  
标签:cnt nums int mask 2572 子集 dp

题目

思路

  • 类似01背包优化的状态压缩dp(误)
  • 首先按照数字分出是否有平方子集,然后再计数cnt[x]
  • 枚举合法的数字(2 ~ 30),为什么不算1?因为所有的1都有两种状态,选或者不选(或者说他不算是质数),直接在最后的结果上\(2^{cnt[1]}\)即可
  • 枚举所有状态(0 ~ 1 << 10, 倒着来是类似01背包的优化),如果和当前状态mask互不相交,递推至mask|j
  • 最后无平方子集的数量就是\((\sum_0^{2^{10}}f) * 2^{cnt[1]} - 1\)

代码

const int mod = 1e9 + 7;
int sum[31];
int p[30] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};
typedef long long LL;
LL f[(1 << 11) + 10];

class Solution {
public:
    int squareFreeSubsets(vector<int> &nums)
    {
        for (int i = 2; i <= 30; i++) 
        {
            for (int j = 0; j < 10; j++)
            {
                if (i % p[j] == 0)
                {
                    if (i % (p[j] * p[j]) == 0)
                    {
                        sum[i] = -1;
                        break;
                    }
                    sum[i] = sum[i] | (1 << j);
                }
            }
        }
        map<int,int>cnt;
        for(int i = 0;i < nums.size();i++)
            cnt[nums[i]]++;
        int v = 1 << 10;
        memset(f,0,sizeof f);
        f[0] = 1;
        for(auto it : cnt)
        {
            int a = it.first;
            int b = it.second;
            int mask = sum[a];
            if(mask > 0)
            {
                for(int i = v;i >= 0;i--)
                {
                    if((i & mask) == 0)
                    {
                        f[i | mask] = (f[i] * b + f[i | mask]) % mod;
                    }
                }
            }
        }
        LL ans = 0;
        int x = cnt[1];
        int y = 1;
        while(x)
        {
            y = y * 2 % mod;
            x--;
        }
        for(int i = 0;i < 1 << 10;i++)
        {
            ans = (f[i] + ans) % mod;
        }

        ans = (ans * y) % mod;
        return (ans+ mod - 1) % mod;
    }
};

标签:cnt,nums,int,mask,2572,子集,dp
From: https://www.cnblogs.com/cfddfc/p/17153861.html

相关文章

  • mybatis 完成树级结构,通过循环添加collection循环添加子集
    有拿到一个树级结构的需求,有子集的状态下,就往下无限添加层级然后一起返回,直接用myabtis的resultMap处理会简单很多,就比方说下面这个结构@DatapublicclassZzztKhpfVo{......
  • TCP/UDP
    TCP与UDP在后台都用到套接字Socket,当准确度要求高的时候,用TCP。若追求性能和速度,而且对准确度要求不高时,用UDP。TCP协议和UDP协议连接过程的区别如下:基于连接与无连接;......
  • 【YBT2023寒假Day15 A】破烂衣裳(Burnside引理)(DP)(矩阵乘法)
    破烂衣裳题目链接:YBT2023寒假Day15A题目大意有一个n个点的环,有k种颜色,一开始都没有颜色。每次你可以选择一个位置,把它染成k种颜色的其中一个,但是相邻的两个位置......
  • 【DP】CF156C
    一开始想了一个复杂度爆炸的DP分析首先考察题目的性质:方便起见,将字符看成是\([0,25]\)的值。注意到操作可以等价于选择任意两个下标,然后对应的两个值一加一减或者一......
  • 动态规划(DP算法)详解
    什么是动态规划:动态规划_百度百科内容太多了不作介绍,重点部分是无后效性,重叠子问题,最优子结构。问S->P1和S->P2有多少种路径数,毫无疑问可以先从S开始深搜两次,S->P1和S->......
  • 【YBT2023寒假Day14 B】二进制数(数位DP)(数学)
    二进制数题目链接:YBT2023寒假Day14B题目大意问你[A,B]之间有多少个整数,满足它二进制表示下(不要前导0)子串00,01,10,11个数分别是a,b,c,d。其中A,B<=2^{100000},a......
  • hdu 4284 Travel(压缩DP,4级)
    TravelTimeLimit:10000/5000MS(Java/Others)    MemoryLimit:32768/32768K(Java/Others)TotalSubmission(s):2641    AcceptedSubmission(s):724......
  • 【微元贡献法 & 连续段 dp】「JOI Open 2016」摩天大楼 - 题解
    「JOIOpen2016」摩天大楼-题解注意到绝对值求和的形式,比较自然地想到将权值\(a\)排序以规避绝对值,下文默认\(a\)按从小到大排序,且插入元素的顺序亦为从小到大。......
  • k8s部署wordpress
    nginxnginx.confserver{listen80;server_namelocalhost;location/{root/apps/nginx/wordpress;indexindex.phpind......
  • TCP和UDP的区别及使用场景
    一、TCP和UDP是什么?   TCP:   传输控制协议(TCP,TransmissionControlProtocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC793定义。   ......