正解:dp

解题报告:

传送门!

首先不难想到求个gcd,然后把gcd质因数分解成p1w1*p2w2*p3w3*...*pmwm

显然只要满足对每个p有一个ai%pj!=0就好,也就是说对每个pj找出一个ai然后代价最小就好

然后这时候就考虑dp

先考虑最简单的,f[i][x][s]:dp到第i个了,改了x个,p的状态为s的最小花费

然后直接枚举删哪个质因子集,判是否合法(<=k)即可

这时候发现复杂度不太对,是O(nm3m)不会分析复杂度不要问我为什么是这个式子,,,

但反正是跑不过去的这个是可以发现的

因为可以发现m<=11(2*3*5*7*11*13*17*19*23*29*31)嘛,这样显然是会T的

所以考虑怎么优化

考虑到我们最开始的那个dp能有一个小优化

那个dp的顺序显然是for(i)for(x)for(S)for(T),其中S指的是原来的状态,T指的是增加的状态嘛

这里可以考虑到,对质因数的倍数的集合,我们只要保留前m个就欧克了,后面显然都是浪费(这里关于集合这个词可能比较难get,,,指的是对每个数,有意义的地方只在那些单纯由gcd的质因数构成的数,所以把每个数的最大的这个有用数拿出来,把这个有用数相当的数就可以作为一个集合辣!(还是说得不太清楚的样子QAQ

继续优化,可以发现对于每个状态其实也只要保留前m个就欧克了

所以对每个状态也只要枚m次,超过了就不枚了

所以考虑改变枚举顺序,先枚T,然后枚T的补集的子集S

然后这里先港下枚举集合的正确姿势

如果现在是要枚举集合满足j是k的子集

显然首先肯定要已知一个集合,就分类讨论下,看是已知j还是已知k

如果是已知j了,就是说枚举包含某个集合的集合,就可以for(ri k=(j+1)|j;k<=S;k=(k+1)|j)

(因为,一般要枚举集合之类的都是在dp转移中,所以就不考虑k=j的情况了QAQ

然后如果是已知k了,就是说枚举某个集合的子集,就可以for(ri j=(k-1)&k;j;j=(j-1)&k)

原理还是挺显然的?实在无法理解手动模拟下就能get辣

然后好像就差不多了?

#include<bits/stdc++.h>
using namespace std;
#define fr first
#define sc second
#define il inline
#define ll long long
#define gc getchar()
#define rl register ll
#define rc register char
#define rb register bool
#define rp(i,x,y) for(rl i=x;i<=y;++i)
#define my(i,x,y) for(rl i=x;i>=y;--i) const ll N=1e6+,M=;
ll n,K,gcdd,fac[M],fac_cnt,f[M][<<M],S,poww[M]={},as,inf;
bool vis[<<M];
struct node{ll a,e;}nod[N];
map< ll,vector<ll> >Mp; il ll read()
{
rc ch=gc;rl x=;rb y=;
while(ch!='-' && (ch>'' || ch<''))ch=gc;
if(ch=='-')ch=gc,y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
return y?x:-x;
}
il ll gcd(rl gd,rl gs){return gs?gcd(gs,gd%gs):gd;} int main()
{
// freopen("ayg.in","r",stdin);freopen("ayg.out","w",stdout);
n=read();K=read();rp(i,,n)nod[i].a=read();rp(i,,n)nod[i].e=read();gcdd=nod[].a;rp(i,,n)gcdd=gcd(gcdd,nod[i].a);
if(!(gcdd^))return printf("0\n"),;
for(rl i=;i*i<=gcdd;++i)if(!(gcdd%i)){fac[fac_cnt++]=i;while(!(gcdd%i))gcdd/=i;}
if(gcdd^)fac[fac_cnt++]=gcdd;
rp(i,,n){rl tmp=;rp(j,,fac_cnt-)while(!(nod[i].a%fac[j]))tmp*=fac[j],nod[i].a/=fac[j];Mp[tmp].push_back(nod[i].e);}
memset(f,,sizeof(f));inf=as=f[][];f[][]=;
S=(<<fac_cnt)-;rp(i,,fac_cnt)poww[i]=poww[i-]<<;
for(auto i:Mp)
{
ll x=i.fr;sort(i.sc.begin(),i.sc.end());if(i.sc.size()>fac_cnt)i.sc.resize(fac_cnt);
rp(j,,S){rl y=x,z=;rp(k,,fac_cnt-)if(j&poww[k])while(!(y%fac[k]))y/=fac[k],z*=fac[k];vis[j]=(z<=K);}
for(auto j:i.sc)
{
bool flg=;
my(k,fac_cnt-,)
rp(p,,S)
if(f[k][p]<inf)
for(rl q=(p+)|p;q<=S;q=(q+)|p)if(vis[q^p])if(f[k+][q]>f[k][p]+j)flg=,f[k+][q]=f[k][p]+j;
if(!flg)break;
}
}
rp(i,,fac_cnt)if(f[i][S]<inf)as=min(as,f[i][S]*i);if(as^inf)printf("%lld\n",as);else printf("-1\n");
return ;
}

这儿是代码QAQ

CF1103D Professional layer dp的更多相关文章

  1. CF1103D Professional layer 状压DP

    传送门 首先对于所有数求gcd并求出这个gcd含有的质因子,那么在所有数中,只有这一些质因子会对答案产生影响,而且对于所有的数,每一个质因子只会在一个数中被删去. 质因子数量不会超过\(11\),所以 ...

  2. 【题解】CF1103D Professional layer

    [题解]CF1103DProfessional layer 神题做前先\(orzyyb\) 一个很好的性质(之前也见过但是没有想到的) zhengchu \(gcd\le 10^{12}\) 所以不同 ...

  3. CF1103D Codeforces Round #534 (Div. 1) Professional layer 状压 DP

    题目传送门 https://codeforces.com/contest/1103/problem/D 题解 失去信仰的低水平选手的看题解的心路历程. 一开始看题目以为是选出一些数,每个数可以除掉一个 ...

  4. HDU 4374 One hundred layer DP的单调队列优化

    One hundred layer Problem Description   Now there is a game called the new man down 100th floor. The ...

  5. Professional layer CodeForces - 1103D (状压,gcd)

    大意: 给定$n$元素序列$a$, 现在想要让$gcd(a_1,a_2,...,a_n)=1$. 对于每个$a_i$可以除以一个不超过$k$的因子, 代价为$e_i$, 假设一共选择了$x$个元素去除 ...

  6. CodeForces 1103D. Professional layer

    题目简述:给定$1 \leq n \leq 10^6$个正整数$1 \leq a_i \leq 10^{12}$,修改第$i$个正整数$a_i$的花费为$1 \leq e_i \leq 10^9$,以 ...

  7. NOI前训练日记

    向别人学习一波,记点流水帐.17.5.29开坑. 5.29 早晨看了道据说是树状数组优化DP的题(hdu5542),然后脑补了一个复杂度500^3的meet in the middle.然后死T... ...

  8. hdu4374One hundred layer (DP+单调队列)

    http://acm.hdu.edu.cn/showproblem.php?pid=4374 去年多校的题 今年才做 不知道这一年都干嘛去了.. DP的思路很好想 dp[i][j] = max(dp[ ...

  9. HDU 4374 One hundred layer(单调队列DP)

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=116242#problem/E 题意:差不多就是男人勇下百层的游戏.从第一层到最 ...

随机推荐

  1. Java多线程系列——线程池简介

    什么是线程池? 为了避免系统频繁地创建和销毁线程,我们可以让创建的线程进行复用.用线程时从线程池中获取,用完以后不销毁线程,而是归还给线程池. JDK 对线程池的支持 为了更好的控制多线程,JDK 提 ...

  2. JVM——Java HotSpot VM Options

    JVM常用参数 参数名称 含义 默认值  描述 -Xms 初始堆大小 物理内存的1/64(<1GB) 默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆 ...

  3. 删除最少字符生成Palindrome

    看到一个哥们G家电面试题,求删除最少字符生成Palindrome.大神们都在讨论dp,我完全想不到. 放一个没优化的DFS. 乐神说是O(n3)复杂度, 有机会的话要减少使用substring,并且要 ...

  4. 总结一下搭建简单Web服务器的一些方法

    使用nodejs+anywhere模块搭建静态文件服务器 anywhere随时随地将你的当前目录变成一个静态文件服务器的根目录. 安装npm install anywhere -g,然后进入任意目录在 ...

  5. [GAN] How to use GAN - Meow Generator

    一篇介绍GAN应用的文章.今后GAN模型学习的主要内容. 中文链接:萌物生成器:如何使用四种GAN制造猫图 原文链接:https://ajolicoeur.wordpress.com/cats/ 项目 ...

  6. [Android] 基于 Linux 命令行构建 Android 应用(五):Ant 构建命令

    Android SDK 提供的 android 工具可以在项目根目录自动生成 Ant 构建文件 build.xml[1].进入项目根目录后,你可以使用以下 Ant 命令[2]. ant clean 清 ...

  7. <aop:aspectj-autoproxy />作用

    通过配置织入@Aspectj切面 虽然可以通过编程的方式织入切面,但是一般情况下,我们还是使用spring的配置自动完成创建代理织入切面的工作. 通过aop命名空间的<aop:aspectj-a ...

  8. 三、K3 Cloud 开发插件《K3 Cloud插件开发新手指导 + K3 Cloud插件开发代码调试》

    案例需求:在销售订单上新增一个按钮,在订单明细中新增一个字段,命名[即时库存]. 点击按钮,弹出“Hello World!”,并获取订单明细物料的即时库存,填入字段[即时库存]. 开发工具:Visua ...

  9. DAX Editor VSIX project

    DAX Editor is a Visual Studio extension that implements a language service for DAX language for SQL ...

  10. 在Android源码中查找Java代码中native函数对应的C++实现

    Android源码中很多关键代码都是C++实现的,java通过jni来调用,经常会看到java中这样的代码: static native Thread currentThread(); 如何根据方法名 ...