51 Nod 1354 选数字(体现动态规划的本质)

时间:2023-12-13 21:51:26

1354 选数字 51 Nod 1354 选数字(体现动态规划的本质)

基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题

51 Nod 1354 选数字(体现动态规划的本质) 收藏

51 Nod 1354 选数字(体现动态规划的本质) 关注

当给定一个序列a[0],a[1],a[2],...,a[n-1] 和一个整数K时,我们想找出,有多少子序列满足这么一个条件:把当前子序列里面的所有元素乘起来恰好等于K。样例解释:

对于第一个数据,我们可以选择[3]或者[1(第一个1), 3]或者[1(第二个1), 3]或者[1,1,3]。所以答案是4。

Input

多组测试数据。在输入文件的第一行有一个整数T(0< T <= 20),表示有T组数据。
接下来的2*T行,会给出每一组数据
每一组数据占两行,第一行包含两个整数n, K(1<=n<=1000,2<=K<=100000000)他们的含意已经在上面提到。
第二行包含a[0],a[1],a[2],...,a[n-1] (1<= a[i]<=K) 以一个空格分开。
所有输入均为整数。

Output

对于每一个数据,将答案对1000000007取余之后输出即可。

Input示例

2
3 3
1 1 3
3 6
2 3 6

Output示例

4
2
#include<bits/stdc++.h>
using namespace std;
const int mod=1000000007;
int t;
int n;
int k;
int a[1005];
map<int,int>mp;
map<int,int>tmp;
map<int,int>::iterator it;
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
scanf("%d",&t);
while(t--)
{
mp.clear();tmp.clear();
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++)scanf("%d",&a[i]);
for(int i=0;i<n;i++)
{
if(k%a[i]==0)
{
for(it=tmp.begin();it!=tmp.end();it++)
{
int num=a[i]*(it->first);
if(k%num==0)mp[num]=(mp[num]+it->second)%mod;
}
mp[a[i]]=(mp[a[i]]+1)%mod;
}
tmp=mp;
}
cout<<mp[k]<<endl;
}
return 0;
}