Codeforces Round #365 (Div. 2) E - Mishka and Divisors(转化成01-背包)
http://codeforces.com/contest/703/problem/E
题意:
给出n个数和一个k,计算出至少要多少个数相乘才是k的倍数。
思路:
这道题目参考了杭电大神的代码http://blog.csdn.net/snowy_smile/article/details/52134304。
对于每个数字,我们要么选,要么不选,这就很像01背包。但是肯定是需要预处理的。
对于每个数字,它所贡献的数就是它和k的最大公因数,这个不难理解吧。
所以我们可以把k的所有因子计算出来,因为有些因子很大,所以这里离散化一下,用map映射,这样后面才开得了数组。
我们用f[i][j]表示前i个数字,它们的gcd乘=映射j状态时的最佳方案。
当我们分析到第i个数字时,它所能贡献的数就是gcd(a[i],v[j]),那么它的前缀就是v[j]/gcd(a[i],v[j]),具体参见代码。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
#include<cmath>
#include<map>
using namespace std;
typedef long long LL;
const int maxn=+; int n;
LL k;
LL s;
LL a[maxn];
LL b[maxn];
pair<int,LL> f[maxn][maxn*];
vector<LL> v;
map<LL,LL> key; LL gcd(LL a,LL b)
{
if(a<b) swap(a,b);
while(b!=)
{
LL t=a;
a=b;
b=t%b;
}
return a;
} void dp()
{
if(k==)
{
puts("");
LL tmp =0x3f3f3f3f3f3f3f3f, ans=-;
for (int i = ; i<=n;++i)
if (a[i]<=tmp)
{
ans=i;
tmp=a[i];
}
printf("%lld\n", ans);
return;
}
for(int j=;j<s;j++) f[][j]=make_pair(n+,);
for(int i=;i<=n;i++)
{
for (int j = ; j < s; ++j)
{
f[i][j] = f[i - ][j];
int pre = key[v[j] / gcd(v[j], b[i])];
f[i][j]=min(f[i][j], make_pair(f[i - ][pre].first + , f[i - ][pre].second + a[i]));
}
}
if (f[n][s-].first > n) puts("-1");
else
{
printf("%d\n", f[n][s-].first);
for (int i = n; i; --i)
{
if (f[i][key[k]] != f[i - ][key[k]])
{
printf("%d ", i);
k /= gcd(k, b[i]);
}
}
puts("");
}
} int main()
{
//freopen("D:\\input.txt","r",stdin);
while(~scanf("%d%lld",&n,&k))
{
LL m=sqrt(k+0.5);
v.clear();
for(int i=;i<=m;i++)
{
if(k%i==)
{
v.push_back(i);
if(k/i!=i) v.push_back(k/i);
}
}
sort(v.begin(),v.end());
s=v.size();
key.clear();
for(int i=;i<s;i++) key[v[i]]=i;
for(int i=;i<=n;i++)
{
scanf("%lld",&a[i]);
b[i]=gcd(k,a[i]);
}
dp();
}
return ;
}
Codeforces Round #365 (Div. 2) E - Mishka and Divisors(转化成01-背包)的更多相关文章
- Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum 离线+线段树
题目链接: http://codeforces.com/contest/703/problem/D D. Mishka and Interesting sum time limit per test ...
- Codeforces Round #365 (Div. 2)-D Mishka and Interesting sum(树状数组)
题目链接:http://codeforces.com/contest/703/problem/D 思路:看了神犇的代码写的... 偶数个相同的数异或结果为0,所以区间ans[l , r]=区间[l , ...
- Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum (离线树状数组+前缀xor)
题目链接:http://codeforces.com/contest/703/problem/D 给你n个数,m次查询,每次查询问你l到r之间出现偶数次的数字xor和是多少. 我们可以先预处理前缀和X ...
- Codeforces Round #365 (Div. 2) D - Mishka and Interesting sum(离线树状数组)
http://codeforces.com/contest/703/problem/D 题意: 给出一行数,有m次查询,每次查询输出区间内出现次数为偶数次的数字的异或和. 思路: 这儿利用一下异或和的 ...
- Codeforces Round #365 (Div. 2) B - Mishka and trip
http://codeforces.com/contest/703/problem/B 题意: 每个点都有一个值,每条边的权值为这两个点相乘.1~n成环.现在有k个城市,城市与其他所有点都相连,计算出 ...
- Codeforces Round #365 (Div. 2) D.Mishka and Interesting sum 树状数组+离线
D. Mishka and Interesting sum time limit per test 3.5 seconds memory limit per test 256 megabytes in ...
- Codeforces Round #365 (Div. 2) D.Mishka and Interesting sum
题目链接:传送门 题目大意:给n个数,m次询问,每次询问区间 l,r 内出现偶数次数的异或和 题目思路:前缀和+离线处理+树状数组 首先可以知道, l,r 内出现奇数次的数的和,就是把 l,r内所有数 ...
- Codeforces Round #360 (Div. 2) E. The Values You Can Make 01背包
题目链接: 题目 E. The Values You Can Make time limit per test:2 seconds memory limit per test:256 megabyte ...
- Codeforces Round #365 (Div. 2) C - Chris and Road 二分找切点
// Codeforces Round #365 (Div. 2) // C - Chris and Road 二分找切点 // 题意:给你一个凸边行,凸边行有个初始的速度往左走,人有最大速度,可以停 ...
随机推荐
- CentOS下调整home和根分区大小的方法
解决外挂硬盘的问题. 目标:将VolGroup-lv_home缩小到20G,并将剩余的空间添加给VolGroup-lv_root 1.首先查看磁盘使用情况[root@jb51.net~]# df -h ...
- 前端开发 - CSS - 下
CSS: 12.display 13.浮动效果 14.浮动特性 15.浮动产生的问题和解决方法 16.float京东导航栏 17.position 18.z-index 19.京东案例 12.disp ...
- Zabbix监控基础
1. 安装前准备 setenforce 0 sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config ...
- git 常用文件目录介绍
生成的RSA公钥与密钥目录: C:\Users\***\.ssh 系统配置文件路径 C:\ProgramData\Git\ C:\Program Files\Git\mingw64\etc 全 ...
- JavaWeb—Tomcat
简介 Tomcat 是由 Apache 开发的一个 Servlet 容器,实现了对 Servlet 和 JSP 的支持,并提供了作为Web服务器的一些特有功能,如Tomcat管理和控制平台.安全域管理 ...
- 解析button和input type=”button”的区别
一.定义和用法 <button> 标签定义的是一个按钮. 在 button 元素内部,可以放置文本或图像.这是<button>与使用 input 元素创建的按钮的不同之处. 二 ...
- 利用google api生成二维码名片
利用google api生成二维码名片 二维条码/二维码可以分为堆叠式/行排式二维条码和矩阵式二维条码.堆叠式/行排式二维条码形态上是由多行短截的一维条码堆叠而成:矩阵式二维条码以矩阵的形式组成,在矩 ...
- 微信小程序组件action-sheet
操作反馈action-sheet:官方文档 Demo Code: Page({ data: { actionSheetHidden: true, actionSheetItems: ['item1', ...
- JQuery变量数字相加的研究
在 jquery中,一个变量和一个数字相加,期望得到1+2=3但是: eg: <input type="text" class="input_Num" i ...
- 自己写个 Drools 文件语法检查工具——栈的应用之编译器检测语法错误
一.背景 当前自己开发的 Android 项目是一个智能推荐系统,用到 drools 规则引擎,于我来说是一个新知识点,以前都没听说过的东东,不过用起来也不算太难,经过一段时间学习,基本掌握.关于 d ...