传送门


首先对于所有数求gcd并求出这个gcd含有的质因子,那么在所有数中,只有这一些质因子会对答案产生影响,而且对于所有的数,每一个质因子只会在一个数中被删去。

质因子数量不会超过\(11\),所以考虑暴力的状压DP:设\(f_{i,j,k}\)表示前\(i\)个数中选出\(j\)个数并删去了集合为\(k\)的质因子的最小代价,转移枚举子集并计算转移是否合法(即第\(i\)个数中当前集合质因子的乘积是否超过\(K\)),复杂度\(O(nm3^m)\)

考虑优化:对每一个数将不能对答案造成影响的因子全部丢掉。对于剩下的数相同的一些数,最多只会选按权值从小到大排序之后前质因子个数个产生贡献。

再加上一些奇怪的优化就可以快很多了。时间复杂度\(O(?m3^m)\)

#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<map>
//This code is written by Itst
using namespace std; #define int long long
inline int read(){
int a = 0;
char c = getchar();
while(!isdigit(c))
c = getchar();
while(isdigit(c)){
a = a * 10 + c - 48;
c = getchar();
}
return a;
} inline int gcd(int a , int b){
int r = a % b;
while(r){a = b; b = r; r = a % b;}
return b;
} #define st first
#define nd second
const int MAXN = 1e6 + 7;
struct zt{
int num , w;
bool operator <(const zt a)const{return w < a.w;}
}now[MAXN];
vector < int > in;
int N , K , allGcd , dp[12][1 << 11] , calc[1 << 11];
map < int , vector < int > > lsh; signed main(){
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
//freopen("out","w",stdout);
#endif
N = read(); K = read();
for(int i = 1 ; i <= N ; ++i){
now[i].num = read();
allGcd = gcd(allGcd , now[i].num);
}
for(int i = 1 ; i <= N ; ++i) now[i].w = read();
if(allGcd == 1) return puts("0") , 0;
for(int i = 2 ; i <= 1e6 && 1ll * i * i <= allGcd ; ++i)
if(allGcd % i == 0){
in.push_back(i);
while(allGcd % i == 0) allGcd /= i;
}
if(allGcd - 1) in.push_back(allGcd);
int M = in.size();
for(int i = 1 ; i <= N ; ++i){
int z = 1;
for(auto j : in)
while(now[i].num % j == 0){
now[i].num /= j;
z *= j;
}
lsh[z].push_back(now[i].w);
}
memset(dp , 2 , sizeof(dp));
dp[0][0] = 0;
for(auto t : lsh){
int x = t.st;
sort(t.nd.begin() , t.nd.end());
if(t.nd.size() > M) t.nd.resize(M);
vector < int > num;
for(int i = 0 ; i < 1 << M ; ++i){
int times = 1 , p = x;
for(int j = 0 ; j < M ; ++j)
if(i & (1 << j))
while(p % in[j] == 0){
p /= in[j];
times *= in[j];
}
num.push_back(times);
}
for(auto p : t.nd){
bool flg = 0;
for(int i = M - 1 ; i >= 0 ; --i)
for(int j = 0 ; j < 1 << M ; ++j)
if(dp[i][j] <= 1e12){
int all = (1 << M) - 1 - j;
for(int k = all ; k ; k = (k - 1) & all)
if(num[k] <= K)
if(dp[i + 1][j | k] > dp[i][j] + p){
dp[i + 1][j | k] = dp[i][j] + p;
flg = 1;
}
}
if(!flg) break;
}
}
int minN = 1e18;
for(int i = 1 ; i <= M ; ++i)
minN = min(minN , dp[i][(1 << M) - 1] * i);
if(minN > 1e12) cout << -1;
else cout << minN;
return 0;
}

CF1103D Professional layer 状压DP的更多相关文章

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

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

  2. BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3336  Solved: 1936[Submit][ ...

  3. nefu1109 游戏争霸赛(状压dp)

    题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109 //我们校赛的一个题,状压dp,还在的人用1表示,被淘汰 ...

  4. poj3311 TSP经典状压dp(Traveling Saleman Problem)

    题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...

  5. [NOIP2016]愤怒的小鸟 D2 T3 状压DP

    [NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...

  6. 【BZOJ2073】[POI2004]PRZ 状压DP

    [BZOJ2073][POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍 ...

  7. bzoj3380: [Usaco2004 Open]Cave Cows 1 洞穴里的牛之一(spfa+状压DP)

    数据最多14个有宝藏的地方,所以可以想到用状压dp 可以先预处理出每个i到j的路径中最小权值的最大值dis[i][j] 本来想用Floyd写,无奈太弱调不出来..后来改用spfa 然后进行dp,这基本 ...

  8. HDU 1074 Doing Homework (状压dp)

    题意:给你N(<=15)个作业,每个作业有最晚提交时间与需要做的时间,每次只能做一个作业,每个作业超出最晚提交时间一天扣一分 求出扣的最小分数,并输出做作业的顺序.如果有多个最小分数一样的话,则 ...

  9. 【BZOJ1688】[Usaco2005 Open]Disease Manangement 疾病管理 状压DP

    [BZOJ1688][Usaco2005 Open]Disease Manangement 疾病管理 Description Alas! A set of D (1 <= D <= 15) ...

随机推荐

  1. Android 自定义AlertDialog的实现

    Android默认的AlertDialog太单调,我们可以通过继承原生的Dialog来实现自定义的Dialog. 本文的自定义Dialog和原生的AlertDialog的创建方式类似,通过一个静态Bu ...

  2. <自动化测试方案_2>第二章、自动化测试是什么?(What)

    第二章.自动化测试是什么?(What) 自动化测试是相对于手工测试而言:通过脚本自动去执行测试用例,从而代替人完成测试工作. 自动化测试相对手工测试优缺点 测试方式 优点 缺点 手工测试 1,完整的对 ...

  3. git 入门教程之版本管理

    版本管理 背景 在上一节中我们已经成功创建版本库并且已经添加test.txt等文件,这一节我们继续讲解如何进行版本控制. 首先我们先查看test.txt 文件有什么内容吧! # 查看文件内容 $ ca ...

  4. 移动Web前端,游客点击商品的收藏按钮,登录完成,回来之后,如何自动收藏

    我们都知道,移动Web端(M站环境下),很多时候,前端是无法判断用户的登录状态的,因为出于安全性考虑,与账号相关的cookie字段一般都是 http-only的. 如果前端想判断用户的登录状态,需要主 ...

  5. linux富规则的案例

    使用firewall-cmd添加富规则: 1.拒绝来自public区域中ip地址为192.168.0.11的所有流量 firewall-cmd --permanent --zone=public -- ...

  6. servlet请求和响应的过程

    1.加载 Servlet类被加载到Java虚拟机中,并且实例化.在这个过程中,web容器(例如tomcat)会调用Servlet类的公开无参构造函数,产生一个Servlet类的实例对象.默认情况下Se ...

  7. aspectj 简单的模拟权限检查、事务、日志记录

    package com.ij34.service; public class Hello { public void he() { System.out.println("执行Hello的h ...

  8. JMeter—常见问题(十四)

    参考<全栈性能测试修炼宝典JMeter实战>第十五章 JMeter常见问题 1.无法产生负载 注意检查各元件是否时禁用状态.JMeter在运行时是以数形式加载各种元件的,如果父节点被禁用, ...

  9. c指针类型的作用

    指针类型的作用 任何类型的指针占用的空间大小都是相同的(32位CPU是4字节:64位CPU是8字节) 既然任何类型的指针占用的空间大小都是相同的,为什么指针还需要类型呢?指针只是指向了一个内存地址,但 ...

  10. SQLServer数据表用法

    数据表定义 数据表(或称表)是数据库最重要的组成部分之一,数据库中以表为组织单位存储数据,数据库只是一个框架,数据表才是其实质内容.数据库管理工具中可以显示数据库中的所有数据表,数据表是数据库中一个非 ...