【题解】选数字 [51nod1354]

【题解】选数字 [51nod1354]

传送门:选数字 \([51nod1354]\)

【题目描述】

共 \(T\) 组测试点,每一组给定一个长度为 \(n\) 的序列和一个整数 \(K\),找出有多少子序列满足子序列中所有元素乘积恰好等于K,答案对 \(1e9+7\) 取模。

【样例】

样例输入:
2
3 3
1 1 3
3 6
2 3 6

样例输出:
4
2

【数据范围】

\(100\%\) \(1 \leqslant T \leqslant 20,\) \(1 \leqslant N \leqslant 1000,\) \(2 \leqslant K \leqslant 10^8,\) \(1 \leqslant a[i] \leqslant K\)

【分析】

考虑 \(01\) 背包,用 \(dp[j]\) 表示乘积等于 \(j\) 的子序列数,原序列中的 \(n\) 个数就是 \(n\) 个物品,其数值就是体积。

\(K\) 的范围有 \(10^8\) 辣莫大,但是会对答案造成影响的只有一部分可整除 \(K\) 的数的 \(dp\) 值,所以还可以优化。

为防止爆空间,\(dp\) 数组开 \(map\) 类型,用指针访问,并且保证里面存的决策点都是可以整除 \(K\) 的数,每次要加入新的物品时判断一下,只有当物品体积 \(a\) 和 \(a\) 乘以决策点都可整除 \(K\) 时,才让该物品使用该决策点。
即 \(dp[a*x]+=dp[x](a|K,x|K,a*x|K)\) 。

时间复杂度为 \(O(T*n*p)\),其中 \(p\) 为 \(K\) 的正约数个数。

【Code】

#include<algorithm>
#include<cstdio>
#include<map>
#define Re register int
using namespace std;
const int P=1e9+7;
const int N=1003;
int x,n,K,T,t,o,a;
map<int,int>dp,tmp;
map<int,int>::iterator it;
inline void in(Re &x){
    int f=0;x=0;char c=getchar();
    while(c<'0'||c>'9')f|=c=='-',c=getchar();
    while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
    x=f?-x:x;
}
int main(){
    in(T);
    while(T--){
        in(n),in(K);
        dp.clear();
        for(Re i=1;i<=n;++i){
            in(a);
            if(K%a)continue;
            tmp=dp;
            for(it=tmp.begin();it!=tmp.end();++it)
                if(a<=K/(x=it->first)&&K/x%a==0)
                    (dp[a*x]+=it->second)%=P;
            (dp[a]+=1)%=P;
        }
        printf("%d\n",dp[K]);
    }
}

原文地址:https://www.cnblogs.com/Xing-Ling/p/11348073.html

时间: 2024-10-16 11:11:04

【题解】选数字 [51nod1354]的相关文章

51nod1354 选数字

01背包tle. 解题报告(by System Message) 类似于背包的DP,以乘积为状态.先把等选数字里面不是K约数的去掉.然后找出K的约数,进行离散化.然后dp[i][j]表示前i个数字乘积为j的状态.Dp[i+1][j*a[i+1]]]+=dp[i][j].Dp[i+1][j]+=dp[i][j];总的复杂度是O(n*d(k)*log(d(k)))D(k)表示k的因子数目.多一个log是因为离散化了,对应下标的时候要二分查找. 其实我觉得就是去掉没用的状态只用他的约数来更新.网上有的

51nod 1354:选数字

51nod 1354:选数字 题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1354 题目大意:有$T(T \leqslant 20)$组数据,每组给出$n(n \leqslant 1000)$个数和$K(K \leqslant 100,000,000)$,问在这$n$个数中选取若干个,积为$K$的方案数有多少. DP+离散化 与01背包类似,定义状态$dp[i][j]$为前$i$个数中选取若干个数,积为$j

题解——[ZJOI2010]数字计数 数位DP

最近在写DP,今天把最近写的都放上来好了,,, 题意:给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. 首先询问的是一个区间,显然是要分别求出1 ~ r ,1 ~ l的答案,然后相减得到最终答案 首先我们观察到,产生答案的区间是连续的,且可以被拆分, 也就是说0 ~ 987的贡献= 0 ~ 900 + 901 ~ 987的恭喜, 同理,把位拆开也是等价的,所以我们可以单独计算每个位的贡献 这样讲可能有点不太清晰,举个例子吧 3872 我们先把它按数拆开来

Lintcode18 Subsets II solution 题解

[题目描述] Given a list of numbers that may has duplicate numbers, return all possible subsets Notice:Each element in a subset must be in non-descending order.The ordering between two subsets is free.The solution set must not contain duplicate subsets. 给

题解报告:hdu 4764 Stone(巴什博弈)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4764 Problem Description Tang and Jiang are good friends. To decide whose treat it is for dinner, they are playing a game. Specifically, Tang and Jiang will alternatively write numbers (integers) on a wh

猜数字游戏的提示 (Master-Mind Hints, UVa 340)

题目: 实现一个经典"猜数字"游戏. 给定答案序列和用户猜的序列,统计有多少数字位置正确(A),有多少数字在两个序列都出现过但位置不对(B). 输入包含多组数据. 每组输入第一行为序列长度n,第二行是答案序列,接下来是若干猜测序列. 猜测序列全0时该组数据结束. n=0时输入结束. 样例输入:4 13 5 51 1 2 34 3 3 56 5 5 16 1 3 51 3 5 50 0 0 0101 2 2 2 4 5 6 6 6 91 2 3 4 5 6 7 8 9 11 1 2 2

由数字三角问题来理解DP

先看几类数字三角形的问题,通过对这几个问题的分析来理解有关动态规划的基本思想 数字三角形I 问题描述: 有一个由正整数组成的三角形,第一行只有一个数,除了最下行之外 每个数的左下方和右下方各有一个数,从第一行的数开始,每次可以往左下或右下走一格,直到走到三角形底端,把沿途经过的数全部加起来作为得分.如何走,使得这个得分尽量大? 分析: 如何走,是一个决策问题,很容易联想到一种贪心策略是:每次选数字大的那个方向走.然而很明显,这种决策方案是错误的.因为如果按这种方案,得到的结果是1→3→10→3,

9.15模拟赛

T1 np问题 题目描述 LYK喜欢研究一些比较困难的问题,比如np问题. 这次它又遇到一个棘手的np问题.问题是这个样子的:有两个数n和p,求n的阶乘对p取模后的结果. LYK觉得所有np问题都是没有多项式复杂度的算法的,所以它打算求助即将要参加noip的你,帮帮LYK吧! 输入输出格式 输入格式: 输入一行两个整数n,p. 输出格式: 输出一行一个整数表示答案. 输入输出样例 输入样例#1: 3 4 输出样例#1: 2 说明 对于20%的数据:n,p<=5. 对于40%的数据:n,p<=1

BZOJ(begin) 1375 [Usaco2009 Mar]Cow Frisbee Team 奶牛沙盘队:dp【和为f的倍数】

题目链接:http://begin.lydsy.com/JudgeOnline/problem.php?id=1375 题意: 给你n个数,你可以从中选任意多个,但不能不选.问你所选数字之和为f的倍数的方案数. 题解: 表示状态: dp[i][j] = num of ways i:考虑到第i个数(还没选) j:之前所选数之和 MOD f == j 找出答案: ans = dp[n][0] - 1 不选也是一种方案,但题目种要求不能不选,所以-1. 如何转移: 选或不选第i个数. dp[i+1][