首页 > 其他分享 >lc996 正方形数组的数目

lc996 正方形数组的数目

时间:2024-03-23 12:22:48浏览次数:12  
标签:cnt lc996 nums int st 正方形 数组 dp

给定非负整数数组A[n],返回A的不同排列数目,使用数组每对相邻元素之和是一个完全平方数。
1<=n<=12; 0<=A[i]<=1e9

状压dp,记dp[st][i]表示已选择数的状态为st,并且最后选择数的下标为i的方案数,对于某个状态st,枚举最后选择的数i是哪个,以及上一个最后选择的数j是哪个,进行转换。
由于A可能存在相同的元素,需要去重,假设A[i]有z个,那由这z个元素构成的相同排序数有z!个,因此答案要除以z!。

class Solution {
public:
    int dp[4096][12];
    bool check(int x) {
        int z = sqrt(x);
        return z * z == x;
    }
    int numSquarefulPerms(vector<int>& nums) {
        int n = nums.size();
        for (int i = 0; i < (1<<n); i++) {
            for (int j = 0; j < n; j++) {
                dp[i][j] = 0;
            }
        }
        for (int st = 1; st < (1<<n); st++) {
            int m = __builtin_popcount(st);
            for (int i = 0; i < n; i++) if (st & (1<<i)) {
                if (m == 1) {
                    dp[st][i] = 1;
                    continue;
                }
                for (int j = 0; j < n; j++) if (j != i && (st & (1<<j)) && check(nums[i]+nums[j])) {
                    dp[st][i] += dp[st^(1<<i)][j];
                }
            }
        }
        int ans = 0;
        for (int i = 0; i < n; i++) {
            ans += dp[(1<<n)-1][i];
        }
        map<int,int> cnt;
        for (auto i : nums) cnt[i] += 1;
        for (auto [k,v] : cnt) {
            for (int i = 1; i <= v; i++) {
                ans /= i;
            }
        }
        return ans;
    }
};

标签:cnt,lc996,nums,int,st,正方形,数组,dp
From: https://www.cnblogs.com/chenfy27/p/18090962

相关文章

  • (Java)猛刷LeetCode——数组知识点篇
    数组Array在连续的内存空间中,存储一组相同类型的元素元素:值索引:数组的下标数组访问(Access)和数组搜索(Search)●数组访问:索引●数组搜索:找2这个元素数组中有没有以下是数组的常规操作:数组创建、添加元素、访问元素、修改元素、删除元素、遍历数组、查找元素、数组......
  • (Python)知识点——数组篇
    在连续的内存空间中,存储一组相同类型的元素元素:值索引:数组的下标数组访问(Access)和数组搜索(Search)●数组访问:索引●数组搜索:找2这个元素数组中有没有常规操作数组的代码如下:#-*-coding:utf-8-*-#@Time:2024-03-2022:14#@Author:Lindand#@Fil......
  • 输入8个整数放入一维数组w中,输出交换前的数组,找出其中的最大数和最小数并将他们分别与
    #include<stdio.h>intmain(){intw[8];inti,maxIndex=0,minIndex=0,temp;//用户输入8个整数printf("请输入8个整数:");for(i=0;i<8;i++){scanf("%d",&w[i]);}//假设第一个元素为最大和最小值......
  • lc992 K个不同整数的子数组
    给定正整数数组nums[n]和一个整数k,返回nums中好子数组的数目。如果nums的某个连续子数组中不同的整数个数恰好为k,则称其为好数组。1<=n<=2e4;1<=nums[i],k<=n先将问题做下转化:恰好为k的个数=最多为k的个数-最多为k-1的个数。而最多为k的个数可以用双指针来解决,固定L并不断......
  • 【LeetCode-153.寻找旋转排序数组的最小值】
    已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums=[0,1,2,4,5,6,7] 在变化后可能得到:若旋转 4 次,则可以得到 [4,5,6,7,0,1,2]若旋转 7 次,则可以得到 [0,1,2,4,5,6,7]注意,数组 [a[0],a[1],a[2],...,a[n-1......
  • 【C语言】空心正方形图案
    思路:1,两行两列打印*:第一行和最后一行,第一列和最后一列。2,其他地方打印空格。代码如下:#include<stdio.h>intmain(){  intn=0;  inti=0;  intj=0;  while(scanf("%d",&n)!=EOF)    for(i=0;i<n;i++)    {......
  • 2605. 从两个数字数组里生成最小数字c
    intminNumber(int*nums1,intnums1Size,int*nums2,intnums2Size){intmin=INT_MAX;for(inti=0;i<nums1Size;i++){intsum=0;for(intj=0;j<nums2Size;j++){if(nums1[i]!=nums2[j]){if(nums1[i]>......
  • LeetCodeHot100 二分查找 35. 搜索插入位置 74. 搜索二维矩阵 34. 在排序数组中查
    35.搜索插入位置https://leetcode.cn/problems/search-insert-position/description/?envType=study-plan-v2&envId=top-100-likedpublicintsearchInsert(int[]nums,inttarget){intleft=0;intright=nums.length-1;while(left<......
  • (41/60)0-1背包(二维数组、一维数组)、分割等和子集
    有点抽象0-1背包卡码网:携带研究材料(第六期模拟笔试)动态规划思路二维:意义:0~i物品内,放进容量为j的背包,最大价值为dp[i][j]递推:dp[i][j]=max(dp[i-1][j-weight[i],dp[i-1][j])初始化:第一列为0,第一行j>=weight[0]时赋值为value[0]遍历:先背包再物品/先物品再背包均可(......
  • 循环控制:(第10题)与闰年相关的问题,涉及数组,函数的知识
    #include<stdio.h>intis_leap_year(intyear){ if((year%4==0&&year%100!=0)||year%400==0) return1; else return0;}intgap_years(intyear){ inti=1990; intsum=0; intgap_years=0; if(year==1990) retur......