E. Mishka and Divisors Codeforces Round #365 (Div. 2) 01背包
2017-11-28 18:29
393 查看
E. Mishka and Diviso
4000
rs
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
After playing with her beautiful array, Mishka decided to learn some math. After learning how to multiply, divide and what is divisibility, she is now interested in solving the following problem.
You are given integer k and array
a1, a2, ..., an ofn integers. You are to find
non-empty subsequence of array elements such that the product of its elements is divisible byk and it contains minimum possible number of elements.
Formally, you are to find a sequence of indices 1 ≤ i1 < i2 < ... < im ≤ n such that
![](http://codeforces.com/predownloaded/2b/ec/2bec6578cb577365a1915ce3f256f59319071cce.png)
is divisible byk while
m is minimum possible among all such variants.
If there are more than one such subsequences, you should choose one among them, such that sum of its elements isminimum possible.
Mishka quickly solved this problem. Will you do so?
Input
The first line of the input contains two integers n andk (1 ≤ n ≤ 1 000,1 ≤ k ≤ 1012).
The second line of the input contains n integersa1, a2, ..., an
(1 ≤ ai ≤ 1012) — array elements.
Output
Print single positive integer m in the first line — the number of elements in desired sequence.
In the second line print m distinct integers — the sequence of indices of given array elements, which should be taken into the desired sequence.
If there are more than one such subsequence (e.g. subsequence of minimum possible number of elements and with minimum possible sum of elements), you can print any of them.
If there are no such subsequences, print - 1 in the only line.
Example
Input
Output
4000
rs
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
After playing with her beautiful array, Mishka decided to learn some math. After learning how to multiply, divide and what is divisibility, she is now interested in solving the following problem.
You are given integer k and array
a1, a2, ..., an ofn integers. You are to find
non-empty subsequence of array elements such that the product of its elements is divisible byk and it contains minimum possible number of elements.
Formally, you are to find a sequence of indices 1 ≤ i1 < i2 < ... < im ≤ n such that
![](http://codeforces.com/predownloaded/2b/ec/2bec6578cb577365a1915ce3f256f59319071cce.png)
is divisible byk while
m is minimum possible among all such variants.
If there are more than one such subsequences, you should choose one among them, such that sum of its elements isminimum possible.
Mishka quickly solved this problem. Will you do so?
Input
The first line of the input contains two integers n andk (1 ≤ n ≤ 1 000,1 ≤ k ≤ 1012).
The second line of the input contains n integersa1, a2, ..., an
(1 ≤ ai ≤ 1012) — array elements.
Output
Print single positive integer m in the first line — the number of elements in desired sequence.
In the second line print m distinct integers — the sequence of indices of given array elements, which should be taken into the desired sequence.
If there are more than one such subsequence (e.g. subsequence of minimum possible number of elements and with minimum possible sum of elements), you can print any of them.
If there are no such subsequences, print - 1 in the only line.
Example
Input
5 60 2 4 6 5 2
Output
3 4 3 1 做这种难题(对于我)真的爽,就算开始一点头绪也没有,但是如果弄懂了会学到很多东西。 这道题01背包,看题目描述的话应该想到类似的解法,就是每个数字只能选一次,让你求出选最优状态,这就类似01背包。 那么怎么规范状态呢。 我们分析一下就可以知道,比如说60的因数是1 2 3 4 5 6 10 12 15 20 30 60这12个数。 设dp【i】【j】的意义为前i个数中选最少的数字相乘为j的倍数的数量。 1.dp[i][j]非递减 2.我们想要得到60,我们可以从剩余11个数字状态转移而来、 3.我们结合01背包,每个数字只有取或者不取,如果不取,那么dp【i】【j】=dp【i-1】【j】,去了就是dp【i】【j】=dp【i-1】【j/gcd(j,s【i】)】 +1(s【i】为给定的数字) 为什么要从dp【i-1】【j/gcd(j,s【i】)】转移而来呢?刚刚说过,dp数组非递减,那么我们要使dp【i】【j】中的j尽可能的小,这样得出的结果才能尽可能的小。 如果j/gcd(j,s【i】)都要比不放要大的话,那么其他的因数自然也就不成立,如果无法达成j/gcd(j,s【i】)这个状态的话,那么其他的因数状态也无法完成,所以这就是正确 的转移方式。 注意,这道题卡常数,非常恶心。在gcd的时候,不要直接gcd(j,s【i】),要先st【i】=gcd(k,s【i】),然后j/gcd(j,st【i】),这样可以少跑一点。
#include<bits/stdc++.h> using namespace std; long long s[1008],st[1008]; int pre[1008][10080]; int dp[10008]; long long sum[10008]; vector<long long> factor; map<long long,int>maped; int div(long long k) { for(long long i=1; i*i<=k; i++) { if(k%i==0) { factor.push_back(i); factor.push_back(k/i); } } sort(factor.begin(),factor.end()); return unique(factor.begin(),factor.end())-factor.begin(); } int main() { int n; long long k; long long Min=LLONG_MAX; int pos; while(scanf("%d%I64d",&n,&k)!=EOF) { for(int i=1; i<=n; i++) { scanf("%I64d",&s[i]); st[i]=__gcd(k,s[i]); if(Min>s[i]) { Min=s[i]; pos=i; } } if(k==1) { printf("%d\n",1); printf("%d\n",pos); continue; } memset(pre,-1,sizeof(pre)); memset(sum,0x3f,sizeof(sum)); memset(dp,0x3f,sizeof(dp)); dp[0]=sum[0]=0; factor.clear(); maped.clear(); int len=div(k); for(int i=0; i<len; i++) { maped[factor[i]]=i; } for(int i=1; i<=n; i++) { for(int j=len-1; j>=1; j--) { long long t=__gcd(factor[j],(long long)st[i]); int pos=maped[factor[j]/t]; if(dp[j]>dp[pos]+1) { dp[j]=dp[pos]+1; sum[j]=sum[pos]+s[i]; pre[i][j]=pos; } if(dp[j]==dp[pos]+1&&sum[j]>sum[pos]+s[i]) { sum[j]=sum[pos]+s[i]; pre[i][j]=pos; } } } if(dp[len-1]>n) { printf("-1\n"); } else { printf("%d\n",dp[len-1]); int a=n,b=len-1; while(a>0&&b>0) { while(pre[a][b]==-1&&a>0&&b>0) a--; printf("%d ",a); b=pre[a--][b]; } } printf("\n"); } }
相关文章推荐
- 【Codeforces Round 365 (Div 2)E】【乘除法DP map映射 约数分解】Mishka and Divisors n个数中选最小数量使得乘积为K的倍数
- Codeforces Round #365 (Div. 2)Mishka and Divisors 题解。 DP
- 【Codeforces Round 365 (Div 2)D】【离线询问 树状数组 前驱思想】Mishka and Interesting sum 区间内出现次数偶数的数的异或和
- Codeforces Round #365 (Div. 2) Mishka and Interesting sum 树状数组
- Codeforces Round #365 (Div. 2) D.Mishka and Interesting sum (树状数组维护异或值) ★ ★
- Codeforces Round #365 (Div. 2) B. Mishka and trip
- Codeforces Round #365 (Div. 2) 703B Mishka and trip 水题
- 【Codeforces Round 365 (Div 2)B】【容斥】Mishka and trip 环加完全点图的边权乘积和
- 【Codeforces Round 365 (Div 2)C】【贪心 极限阻碍思想】 Chris and Road 过马路不被凸包车碰撞的最小时间
- Codeforces Round #182 (Div. 1) D. Yaroslav and Divisors
- Codeforces Round #365 (Div. 2) C. Chris and Road
- Codeforces Round #365 (Div. 2) D.Mishka and Interesting sum 树状数组+离线
- Codeforces Round #199 (Div. 2) A. Xenia and Divisors
- 【Codeforces Round 365 (Div 2)A】【水题】Mishka and Game
- Codeforces Round #206 (Div. 2) E-Vasya and Beautiful Arrays
- Codeforces Round #253 (Div. 2)——Borya and Hanabi
- 【Codeforces Round 370 (Div 2) E】【线段树 等比数列 区间合并】Memory and Casinos 赌场区间[l,r] l进r先出的概率
- Codeforces Round #370 (Div. 2) C. Memory and De-Evolution【dfs+想法】
- Codeforces Round #252(Div. 2) 441B. Valera and Fruits 贪心
- Codeforces Round #290 (Div. 2) C. Fox And Names 拓扑排序