题意:给你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. 最短路径问题的Dijkstra算法

      问题 最短路径问题的Dijkstra算法 是由荷兰计算机科学家艾兹赫尔·戴克斯特拉提出.迪科斯彻算法使用了广度优先搜索解决非负权有向图的单源最短路径问题,算法终于得到一个最短路径树>    ...

  2. 监控mysql状态并发送Email

    */10 * * * *  /shell/mysql_status.sh > /dev/null 2>&1 #!/bin/bash port55=`/usr/sbin/lsof - ...

  3. OPCClient和OPCServer在Windows上运行方式的恩怨

    http://www.diangon.com/wenku/PLC/201504/00021970.html 近段时间,遇到不少人都被OPCClient与OPCServer之间的通讯搞得头大,通过几次远 ...

  4. jq 合并json对象

    一,保存object1和2合并后产生新对象,若2中有与1相同的key,默认2将会覆盖1的值 1 var object = $.extend({}, object1, object2); 二,将2的值合 ...

  5. k8s1.4.3安装实践记录(3)下载基础镜像

    下载基础镜像,因为Google被墙,所以我们用时速云中的镜像来tag docker pull index.tenxcloud.com/google_containers/pause-amd64:3.0 ...

  6. 写一个trim函数,兼容IE firefox chrome(正则)

    因为在获取输入框内容时,常常trim下多余的空格.而IE部分低端浏览器里的JavaScript版本不内置trim()这个清楚空格函数,而流行的浏览器里都兼容了,比如chrome,FF等.为了不让IE下 ...

  7. Masking operations

    Using a mask, multiple bits in a nibble, byte, words can be set either on, off or inverted from on t ...

  8. Ubuntu Server如何配置SFTP(建立用户监狱)

    Ubuntu Server如何配置SFTP(建立用户监狱)   SSH File Transfer Protocol是一个比普通FTP更为安全的文件传输协议.(参考资料:http://en.wikip ...

  9. 深入浅出 Java Concurrency (13): 锁机制 part 8 读写锁 (ReentrantReadWriteLock) (1)

      从这一节开始介绍锁里面的最后一个工具:读写锁(ReadWriteLock). ReentrantLock 实现了标准的互斥操作,也就是一次只能有一个线程持有锁,也即所谓独占锁的概念.前面的章节中一 ...

  10. 18_java之集合Collection

    01集合使用的回顾 *A:集合使用的回顾 *a.ArrayList集合存储5个int类型元素 public static void main(String[] args) { ArrayList< ...