题意:给你n个数,和一个数m, 问最小需要多少个数,可以让这些数乘起来是m的倍数。如果有多组,取和最小的那一组。

思路:因为m的范围到1e12,并且和取模相关,所以容易想到处理出m的约数,然后离散化一下,降低DP的第二维的复杂度,因为如果这些数的乘积不是m的约数,就没有意义了。dp[i][j]表示处理到第i个数,约数是j的最小个数。dp需要存pair,因为要求个数一样的时候和最小。可以提前把a和m求gcd以降低复杂度,注意特判m为1的情况。

代码:

#include <bits/stdc++.h>
#define LL long long
#define pii pair<LL, LL>
#define INF 1e16
using namespace std;
const int maxn = 1010;
pii dp[maxn][7010];
map<LL, int> mp;
LL f[7010], tot;
int n;
LL m, a[maxn], b[maxn];
void init(LL x) {
for (LL i = 1; i * i <= x; i++) {
if(x % i == 0) {
f[++tot] = i;
if(i * i != x)
f[++tot] = x / i;
}
}
sort(f + 1, f + 1 + tot);
for (int i = 1; i <= tot; i++)
mp[f[i]] = i;
}
int main() {
scanf("%d%lld", &n, &m);
init(m);
for (int i = 1; i <= n; i++) {
scanf("%lld", &a[i]);
b[i] = __gcd(a[i], m);
}
if(m == 1) {
LL ans = 1e15, pos = 0;
for (int i = 1; i <= n; i++) {
if(a[i] < ans) {
ans = a[i];
pos = i;
}
}
printf("%d\n%lld\n", 1, pos);
return 0;
}
for (int i = 2; i <= tot; i++)
dp[0][i] = pii(INF, 0);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= tot; j++) {
dp[i][j] = dp[i - 1][j];
int pos = mp[f[j] / __gcd(f[j], b[i])];
pii tmp = pii(dp[i - 1][pos].first + 1, dp[i - 1][pos].second + a[i]);
dp[i][j] = min(dp[i][j], tmp);
}
}
if(dp[n][tot].first > n) printf("-1\n");
else {
printf("%lld\n", dp[n][tot].first);
LL now = f[tot], pos = tot;
for (int i = n; i >= 1; i--) {
if(dp[i][pos] != dp[i - 1][pos]) {
printf("%d ", i);
now /= __gcd(b[i], now);
pos = mp[now];
}
}
}
}

  

Codeforces 703E DP + 因数分解 +离散化的更多相关文章

  1. codeforces 703E Mishka and Divisors

    codeforces 703E Mishka and Divisors 题面 给出大小为\(1000\)的数组和一个数\(k\),求长度最短的一个子序列使得子序列的元素之积是\(k\)的倍数,如果有多 ...

  2. CodeForces - 55D(数位dp,离散化)

    题目来源:http://codeforces.com/problemset/problem/55/D Volodya is an odd boy and his taste is strange as ...

  3. Codeforces 55D. Beautiful numbers(数位DP,离散化)

    Codeforces 55D. Beautiful numbers 题意 求[L,R]区间内有多少个数满足:该数能被其每一位数字都整除(如12,24,15等). 思路 一开始以为是数位DP的水题,觉得 ...

  4. CodeForces - 55D - Beautiful numbers(数位DP,离散化)

    链接: https://vjudge.net/problem/CodeForces-55D 题意: Volodya is an odd boy and his taste is strange as ...

  5. 洛谷2344 奶牛抗议(DP+BIT+离散化)

    洛谷2344 奶牛抗议 本题地址:http://www.luogu.org/problem/show?pid=2344 题目背景 Generic Cow Protests, 2011 Feb 题目描述 ...

  6. [Codeforces]817F. MEX Queries 离散化+线段树维护

    [Codeforces]817F. MEX Queries You are given a set of integer numbers, initially it is empty. You sho ...

  7. Two Melodies CodeForces - 813D (DP,技巧)

    https://codeforces.com/problemset/problem/813/D dp[i][j] = 一条链以i结尾, 另一条链以j结尾的最大值 关键要保证转移时两条链不能相交 #in ...

  8. Consecutive Subsequence CodeForces - 977F(dp)

    Consecutive Subsequence CodeForces - 977F 题目大意:输出一序列中的最大的连续数列的长度和与其对应的下标(连续是指 7 8 9这样的数列) 解题思路: 状态:把 ...

  9. codeforces的dp专题

    1.(467C)http://codeforces.com/problemset/problem/467/C 题意:有一个长为n的序列,选取k个长度为m的子序列(子序列中不能有位置重复),求所取的k个 ...

随机推荐

  1. Let’s Encrypt 将于 2018 年免费提供通配符证书

    旨在让每个网站都启用 HTTPS 加密的 Let's Encrypt CA 宣布将于 2018 年 1 月免费提供通配符证书(Wildcard certificate).通配符证书是一种可被多个子域使 ...

  2. 基于C#的UDP协议的同步实现

    一.摘要 总结基于C#的UDP协议的同步通信. 二.实验平台 Visual Studio 2010 三.实验原理 UDP传输协议同TCP传输协议的区别可查阅相关文档,此处不再赘述. 四.实例  4.1 ...

  3. STL容器——对map排序

    STL容器(三)——对map排序 对于map的排序问题,主要分为两部分:根据key排序:根据value排序.下面我们就分别说一下~ 1. 根据key进行排序 map默认按照key进行升序排序 ,和输入 ...

  4. 对SQLite数据库操作 操作db文件

    sqlite数据库就是一个DB文件.  程序每操作一次数据库都要读一次 .DB  文件 .  这个文件就是这个SQLite数据库. 如果需要依赖包的可以联系我 工具类: package com.hot ...

  5. adb命令记录

    1.杀掉 adb 进程    adb kill-server 2.重启 adb 服务    adb start-server 3.重启手机         adb reboot 4.进 shell 模 ...

  6. OD 实验(十四) - 内嵌补丁

    内嵌补丁(inline patch): 内嵌补丁指在程序文件中把补丁代码写入文件里面达到破解的目的 如果修改某行语句会影响后面的语句,例如某语句占用 3 个字节,修改完变为 5 个字节,会覆盖后面的语 ...

  7. 【转】Android 中处理崩溃异常并重启程序出现页面重叠的问题

    原文地址:http://blog.csdn.net/jiang547860818/article/details/53641113 android开发中经常会遇到程序异常,而已常常会遇到一出现异常AP ...

  8. CentOS7.6安装稳定版Nginx

    官网地址:http://nginx.org/en/linux_packages.html#RHEL-CentOS 需先安装依赖:sudo yum install -y yum-utils 安装开始: ...

  9. [z]计算机架构中Cache的原理、设计及实现

    前言 虽然CPU主频的提升会带动系统性能的改善,但系统性能的提高不仅仅取决于CPU,还与系统架构.指令结构.信息在各个部件之间的传送速度及存储部件的存取速度等因素有关,特别是与CPU/内存之间的存取速 ...

  10. 新浪微博Oauth2.0授权 获取Access Token

    新浪微博开放平台提供了丰富的API接口,利用这些接口,开发者能够开发出独具特色的微博应用.但是,大部分接口都需要用户授权给应用,应用利用授权得到的Access Token来调用相应的接口来获取内容. ...