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

1354 选数字 

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

 收藏

 关注

当给定一个序列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;
}

 

posted @ 2018-10-22 20:15  erge1998  阅读(169)  评论(0编辑  收藏  举报