小明の魔法计划
Time Limit: 1000MS
Memory Limit: 65536KB
Problem Description
在一个遥远的数学魔法国度,小明在学习一个魔法,这个魔法需要一些施法材料,所幸的是施法材料已经准备好了,下一步就是建立魔法阵了,每一个施法材料都有一个特性值,表示为一个大于1小于10 ^ 7的整数,当且仅当一个材料的特性值是另一个材料的特性值的倍数的时候,他们才可以建立法力连接。比如说,一个特性值为6和一个特性值为9的施法材料是不可以建立法力连接的,而一个特性值为9和一个特性值为18的材料是可以建立法力连接的,值得注意的是法力连接是双向的。一个稳定的魔法阵要求属于这个法阵的材料之间不存在任何两个不直接连接的施法材料,比如说由(1,3,9)组成的魔法阵是稳定的,而(3,6,9)组成的魔法阵是不稳定的,因为值为6和值为9的材料无法建立连接。一个魔法阵的威力定义为这个法阵需要的材料的个数。
现在小明已经收集到了一些材料,他想要知道在知道他收集的材料的特性值的前提下,能建立的最大威力的魔法阵的消耗材料的数量是多少。
Input
首先一个整数T,代表数据组数(T<=80)
对于每一组数据,第一行是一个整数n,代表小明收集的施法材料的数量(1 < = n < = 1000)
接下来一行一个有n个数,以空格隔开,分别代表n个施法材料的特性值,每个数1 < = a < = 10 ^ 7
具体见样例
Output
每组数据输出一行一个整数,代表最大威力的魔法阵的需要的材料的个数
Example Input
2
5
1 2 4 8 16
8
12 24 1 2 4 8 72 16
Example Output
5 6
Hint
魔法阵不一定是矩阵,施法材料可以随意摆放。
Author
QAsQ
/***
** 题目的意思就是先把数据进行排序
** 然后找出找出里面的最长的连续可以整除的子序列的个数 (注意各个数字的差值不同)
** 例如 :1 2 4 8 16 48 的连续乘积长度为 6 但是 48/16 = 3 不同于前面的2倍差值
** 算法就是动态规划,类似于 求出最长的上升子序列的长度
***/
#include <bits/stdc++.h>
using namespace std;
int a[100000]= {0};
int dp[10000+100];
int main()
{
int t,n;
cin>>t;
while(t--)
{
cin>>n;
for(int i=0; i<n; i++)
{
cin>>a[i];
}
sort(a,a+n);/// 先对序列排序
memset(dp,0,sizeof(dp));/// dp 数组初始化
dp[0]=1;
for(int i=0; i<n; i++)
{
long long ans=0;
for(int j=0; j<i; j++)
{
if(a[i]%a[j]==0)/// 可以整除
{
if(dp[j] >ans)
{
ans = dp[j];
}
}
}
dp[i]= ans+1;
}
long long max_ans =0;
for(int i=0; i<n; i++)/// 找出最长的数值
{
if(max_ans < dp[i])
{
max_ans = dp[i];
}
}
cout<<max_ans<<endl;
}
return 0;
}