CF1103D Professional layer 状压DP
首先对于所有数求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的更多相关文章
- CF1103D Codeforces Round #534 (Div. 1) Professional layer 状压 DP
题目传送门 https://codeforces.com/contest/1103/problem/D 题解 失去信仰的低水平选手的看题解的心路历程. 一开始看题目以为是选出一些数,每个数可以除掉一个 ...
- BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3336 Solved: 1936[Submit][ ...
- nefu1109 游戏争霸赛(状压dp)
题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109 //我们校赛的一个题,状压dp,还在的人用1表示,被淘汰 ...
- poj3311 TSP经典状压dp(Traveling Saleman Problem)
题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...
- [NOIP2016]愤怒的小鸟 D2 T3 状压DP
[NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...
- 【BZOJ2073】[POI2004]PRZ 状压DP
[BZOJ2073][POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍 ...
- bzoj3380: [Usaco2004 Open]Cave Cows 1 洞穴里的牛之一(spfa+状压DP)
数据最多14个有宝藏的地方,所以可以想到用状压dp 可以先预处理出每个i到j的路径中最小权值的最大值dis[i][j] 本来想用Floyd写,无奈太弱调不出来..后来改用spfa 然后进行dp,这基本 ...
- HDU 1074 Doing Homework (状压dp)
题意:给你N(<=15)个作业,每个作业有最晚提交时间与需要做的时间,每次只能做一个作业,每个作业超出最晚提交时间一天扣一分 求出扣的最小分数,并输出做作业的顺序.如果有多个最小分数一样的话,则 ...
- 【BZOJ1688】[Usaco2005 Open]Disease Manangement 疾病管理 状压DP
[BZOJ1688][Usaco2005 Open]Disease Manangement 疾病管理 Description Alas! A set of D (1 <= D <= 15) ...
随机推荐
- Android为TV端助力 切换fragment的两种方式
使用add方法切换时:载入Fragment1Fragment1 onCreateFragment1 onCreateViewFragment1 onStartFragment1 onResume用以下 ...
- 快速开发跨平台应用之Xamarin技术
Xamarin 介绍 Xamarin 是一个允许开发人员有效创建可跨 iOS.Android.Windows 应用程序的开发工具集.Xamarin是免费且开源的,遵循 MIT (麻省理工学院许可证)协 ...
- git 入门教程之分支策略
默认情况下合并分支常常直接使用 git merge 命令,是最方便快速的合并方法.其实这种情况下 git 采用的是 fast forward 模式,特点是删除分支后,会丢失分支信息,好像从来没存在该分 ...
- (后端)项目中的错误之java中判断字符里面含有某些字符
数据库的数据出现了数据错误.找到原因是因为代码里面Spring的判断所导致的.其实就是判断字符里有01,走这里,有02,走那里,全是if,但是是类似indexOf的那种判断,偏偏有一个数据是0102, ...
- C++反射机制:可变参数模板实现C++反射
1. 概要 本文描述一个通过C++可变参数模板实现C++反射机制的方法.该方法非常实用,在Nebula高性能网络框架中大量应用,实现了非常强大的动态加载动态创建功能.Nebula框架在Github ...
- SQL SERVER 查看占用tempDB
use tempdb go t1.session_id, t1.internal_objects_alloc_page_count, t1.user_objects_alloc_page_count, ...
- MYSQL主从同步/主主同步
一.MYSQL主从同步 注意:进行主从同步操作时需要确保DB无写操作 flush tables with read lock: //全局读锁定,执行了命令之后所有库所有表都被锁定只读. 1.在主机 ...
- python中自定义模块的引用
在python中,实现能够在任何路径下都可以直接import,就必须将存放函数或类的文件添加到python的搜索路径. 其实很简单,主要步骤就是: import sys sys.path.append ...
- wordpress安装后访问博客只显示文字的解决办法
按着网上的教程,买了腾讯云服务器,上面的镜像已经安装好WordPress了.但是发现并不像网上十分钟搭建个人站点等的写的那么简单.遇到了一些问题,下面来详细讲一讲. 首先是用ip地址不能直接访问服务器 ...
- linux c 语言之--fseek(),fseeko(),fseeko64()讲解 (转载)
转载:http://blog.csdn.net/lemoncyb/article/details/16841317 fseek() 函数讲解: 函数定义: int fseek(FILE *stream ...