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是因为离散化了,对应下标的时候要二分查找。

其实我觉得就是去掉没用的状态只用他的约数来更新。网上有的题解用map也是避免了没用的状态。

#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define clr(x,c) memset(x,c,sizeof(x))
int read(){
	int x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-‘0‘,c=getchar();
	return x;
}
const int nmax=1e4+5;
const int mod=1e9+7;
int a[nmax],ans[nmax];
void mm(int &a) {
	if(a>=mod) a-=mod;
}
int main(){
	int T=read();
	while(T--){
		int n=read(),k=read(),cnt=0,u,v,d;
		for(v=1;v*v<k;v++) if(k%v==0) a[++cnt]=v,a[++cnt]=k/v;
		if(v*v==k) a[++cnt]=v;
		sort(a+1,a+cnt+1);
		rep(i,1,cnt) ans[i]=0;ans[1]=1;
		rep(i,1,n){
			u=read();if(k%u) continue;
			dwn(j,cnt,1) {
				v=lower_bound(a+1,a+cnt+1,a[j]*u)-a;
				if(a[v]==a[j]*u) mm(ans[v]+=ans[j]);
			}
		}
		printf("%d\n",ans[cnt]);
	}
	return 0;
}

  

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
时间: 2024-10-13 13:00:24

51nod1354 选数字的相关文章

【题解】选数字 [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 \l

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

猜数字游戏的提示 (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,

ZOJ - 3872 Beauty of Array

题意:给定一个含有N个数的序列S,定义序列的魅力值为序列中不同数字之和,求出该序列所有子序列的魅力值之和. 分析:每个数乘以它出现的次数,求和即可. 如何求每个数出现的次数? 1.对于一个各数字完全不同的序列, eg:3 5 2 6 8 对于5来说,确定其存在于的子序列 (1)其右面,可选0个数字---5  可选1个数字---3 5 (2)其右面,可选0个数字---5  可选1个数字---5 2  可选2个数字---5 2 6        可选3个数字---5 2 6 8 因此,2 * 4 =

LeetCode 561. Array Partition I(easy难度c++)

题目: Given an array of 2n integers, your task is to group these integers into n pairs of integer, say (a1, b1), (a2, b2), -, (an, bn) which makes sum of min(ai, bi) for all i from 1 to n as large as possible. Example 1: Input: [1,4,3,2] Output: 4 Expl

怎样设置PL/SQL的日期显示格式

笑谈:在进入到公司的一段时间里,总是会遇见各种各样的小问题,但最后还是"找度娘,问谷哥"解 决了.但最近公司新招了几个新人,小问题一堆一堆的,PL/SQL连接不上数据库了,怎么通 过PL/SQL找到自己的配置文件.怎么查询出来的日期格式不正确....... 描述:有时候在使用pl/sql的时候,日期不能正常显示,显示的是后缀带E的格式, 需要转换成正常的格式. 设置:工具(Tool)    è                   选项(Preference)       è  窗口类型

House Robber理解分析

上原题:You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will a

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