DFS之剪枝(上交考研题目--正方形数组的数目)

题目

给定一个非负整数数组 A A A,如果该数组每对相邻元素之和是一个完全平方数,则称这一数组为正方形数组。

返回 A A A 的正方形排列的数目。

两个排列 A 1 A1 A1 和 A 2 A2 A2 不同的充要条件是存在某个索引 i i i,使得 A 1 i ≠ A 2 i A1i \neq A2i A1i=A2i。

输入格式

第一行包含一个整数 n n n,表示数组 A A A 的长度。

第二行包含 n n n 个整数 A i Ai Ai。

输出格式

一个整数,表示 A A A 的正方形排列的数目。

数据范围

1 ≤ n ≤ 12 1 \le n \le 12 1≤n≤12,
0 ≤ A i ≤ 1 0 9 0 \le Ai \le 10^9 0≤Ai≤109。

输入样例:
复制代码
3
1 17 8
输出样例:
复制代码
2
样例解释

1 , 8 , 17 1,8,17 1,8,17 和 17 , 8 , 1 17,8,1 17,8,1 都是有效的排列。

思路:使用DFS() 注意使用全排列会有重复

solution1 : 使用set()进行去重,然后在进行判断

solution2 :直接进行得到最终的cnt,然后用 假设原来有6个0,6个1,计算得到cnt=74,649,600 那么直接用 74,649,600/6!/6! = 144 ,得到cnt=144
但是没有通过

说明我们不能取完全部的排列,要剪枝

怎么减?

假如我们规定好在相同的数字中,索引小的一定排在前面,那么就不会有重复了。

python 复制代码
from itertools import permutations as per
import math
N = int(input())
s = [0] + list(map(int,input().split()))
d = dict()
for i in s:
    if i in d.keys():
         d[i] += 1
    else:d[i]  = 1
state = [ False for i in range(N+1)]
def judge(string,i,x):
    if (int(x) - int(math.sqrt(int(x)))*int(math.sqrt(int(x))))>1e-5 :return False
    else:
        for x in string:
            if s[i] == s[x] and i<x:return False
    #print(string,i)
    return True

cnt = 0

def DFS(string,n,last):
    global N,cnt
    if n == N+1:
        cnt+=1;return 
    
    for i in range(1,N+1):
        if (n==1) or (not state[i] and n>1 and judge(string,i,s[i] + last)):
            state[i] = True
            DFS(string+[i],n+1,s[i])
            state[i] = False
string = []
DFS(string,1,0)
'''
fact = [ 1 for i in range(13)]

for i in range(1,13):
    fact[i] = fact[i-1]*i
    
for i in d.values():
    cnt//=fact[i]
'''
print(cnt)

就可以AC了

相关推荐
richard_yuu6 小时前
动态规划:强化学习的「数学基础」,从 MDP 到值迭代
深度学习·神经网络·算法·yolo·机器学习·动态规划
mmmmath_36 小时前
LeetCode.225.用队列实现栈
算法
Elaine3366 小时前
数据结构与算法-程序
数据结构·python·算法·计算机基础·编程基础
2601_965742226 小时前
布局GEO AI本地营销,我重点看这几个细节
大数据·人工智能·算法·ai·新媒体运营
EatFan6 小时前
AI Agent 上生产前先加三道闸门:审批、限权、可回放的工程实践
人工智能·python·算法·多智能体·ai agent·mcp·harness
思茂信息7 小时前
CST软件BCI仿真模型及仿真案例
开发语言·单片机·嵌入式硬件·算法·emc
Persistent的粽子!7 小时前
双指针算法:最大盛水容器
c++·算法·leetcode
hold?fish:palm8 小时前
44 二叉搜索树中第K小的元素
开发语言·c++·算法
Chen—LSN8 小时前
C语言——⽂件操作(1)
c语言·开发语言·c++·经验分享·笔记·算法·链表
anew___8 小时前
《从零手写操作系统 (11):文件系统初探——initrd与VFS抽象层》
java·javascript·算法