【算法】数论,二分图最大匹配

【题意】有无限张牌,给定n张面朝上的牌的坐标(N<=100),其它牌面朝下,每次操作可以选定一个>=3的素数p,并翻转连续p张牌,求最少操作次数使所有牌向下。

【题解】

1.定义bi,当ai和ai-1的朝向相同时,bi=0,否则bi=1。特别的,a0朝向下。

则问题转化为:给定01序列b[],每次选L(正数)和P(奇素数),翻转bL和bP,求最少操作次数使序列全0。

这么转化的关键在于差分,对于区间翻转,区间内的点bi都不会变化,只有区间左端和区间右端+1变化,将区间差分为两点

如此每次操作变成了对两点操作!大大简化了题目。

2.由于每次只能翻转2个数,考虑所有1之间的两两关系

若|i-j|是一个奇素数,操作次数为1。

若|i-j|是一个偶数,操作次数为2。(不严格,此处的意思是一个偶数可以分解为两个奇素数的加减结果)

若|i-j|是一个奇合数(或1),操作次数为3。(分解为偶数减奇素数的差)

素数与合数的关系通过手算小数据就可以得出,然后大胆推广到自然数范围内。

1的总数是偶数?证明:对于a[]中的一段1,b[]对应有2个1。

为什么每次处理两个1是最优的?感性理解:另外把0翻转成1没有收益,把1翻转成0不满足操作。

3.按照每个1所在位置是奇数和偶数分成两组m1,m2,同组内配对是偶数,不同组配对是奇数,定义k为两组配对产生的奇素数的对数。

ans=k*1+(m1-k)/2*2+(m2-k)/2*2+(m1-k)%2*3。

k为1次,剩余的组内配对为2次,最后各组有剩1个再配对为3次。

显然k要尽可能大,对两组建立二分图,差为奇素数连边,跑二分图最大匹配即可。

最坏复杂度O(n^3)。

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn=,maxL=,inf=0x3f3f3f3f;
struct cyc{int v,flow,from;}e[maxn*maxn*];
int tot=,cnt,n,first[maxn],d[maxn],S,T,num[maxn],b[maxn],cur[maxn];
bool c[maxL];
inline int ab(int x){return x>?x:-x;}
bool isprime(int x){
if(x<=)return ;
for(int i=;i*i<=x;i++)if(x%i==)return ;
return ;
}
void insert(int u,int v,int w){
tot++;e[tot].v=v;e[tot].flow=w;e[tot].from=first[u];first[u]=tot;
tot++;e[tot].v=u;e[tot].flow=;e[tot].from=first[v];first[v]=tot;
}
queue<int>q;
bool bfs(){
memset(d,-,sizeof(d));
q.push(S);d[S]=;
while(!q.empty()){
int x=q.front();q.pop();
for(int i=first[x];i;i=e[i].from)
if(d[e[i].v]==-&&e[i].flow){
d[e[i].v]=d[x]+;
q.push(e[i].v);
}
}
return d[T]!=-;
}
int dinic(int x,int a){
if(x==T||a==)return a;
int f,flow=;
for(int& i=cur[x];i;i=e[i].from)
if(d[e[i].v]==d[x]+&&e[i].flow&&(f=dinic(e[i].v,min(a,e[i].flow)))>){
e[i].flow-=f;
e[i^].flow+=f;
a-=f;
flow+=f;
if(a==)break;
}
return flow;
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++){scanf("%d",&num[i]);c[num[i]]=;}
for(int i=;i<=maxL-;i++)if(c[i]!=c[i-])b[++cnt]=i;
S=;T=cnt+;
int m1=;
for(int i=;i<=cnt;i++)if(b[i]&){
m1++;
insert(S,i,);
for(int j=;j<=cnt;j++)if(!(b[j]&)&&isprime(ab(b[i]-b[j])))insert(i,j,);
}else{
insert(i,T,);
}
int ans=;
while(bfs()){
for(int i=S;i<=T;i++)cur[i]=first[i];
ans+=dinic(S,inf);
}
printf("%d",cnt-ans+(m1-ans)%);
return ;
}

【Atcoder】ARC 080 F - Prime Flip的更多相关文章

  1. 【Atcoder】ARC 080 E - Young Maids

    [算法]数学+堆 [题意]给定n个数的排列,每次操作可以取两个数按序排在新序列的头部,求最小字典序. [题解] 转化为每次找字典序最小的两个数按序排在尾部,则p1和p2的每次选择都必须满足:p1在当前 ...

  2. 【AtCoder】ARC 081 E - Don't Be a Subsequence

    [题意]给定长度为n(<=2*10^5)的字符串,求最短的字典序最小的非子序列字符串. http://arc081.contest.atcoder.jp/tasks/arc081_c [算法]字 ...

  3. 【AtCoder】 ARC 097

    link C-K-th Substring 题意:找出已知串中第\(k\)大的子串,子串相同的不算 \(k\)好小啊,要怎么做啊 不是[Tjoi2015]弦论吗 算了,直接SAM吧 #include& ...

  4. 【AtCoder】ARC096(C - F)

    听说日本题思维都很棒,去涨涨智商qwq C - Half and Half 题解 枚举买多少个AB披萨也行 但是关于买x个AB披萨最后的总花费是个单峰函数,可以三分 这题有点像六省联考2017D1T1 ...

  5. 【AtCoder】 ARC 096

    link C-Half and Half 题意:三种pizza,可以花\(A\)价钱买一个A-pizza,花\(B\)价钱买一个B-pizza,花\(C*2\)价钱买A-pizza和B-pizza各一 ...

  6. 【AtCoder】 ARC 098

    link C-Attention 题意:一个字符队列,每个位置是\(W\)或\(E\),计算最小的修改数量,使得存在一个位置,它之前的都是\(E\),之后的都是\(F\) #include<bi ...

  7. 【AtCoder】 ARC 099

    link C-Minimization 枚举覆盖\(1\)的区间,两边的次数直接算 #include<bits/stdc++.h> #define ll long long #define ...

  8. 【AtCoder】 ARC 100

    link C-Linear Approximation 给出\(N\)个数\(A_1,A_2,...,A_N\) ,求一个数\(d\),最小化\(\sum_{i=1}^N|A_i-(d+i)|\) 把 ...

  9. 【AtCoder】 ARC 101

    link 搬来了曾经的题解 C-Candles 题意:数轴上有一些点,从原点开始移动到达这些点中的任意\(K\)个所需要的最短总路程 \(K\)个点必然是一个区间,枚举最左边的就行了 #include ...

随机推荐

  1. 自动化测试--封装JDBCUnit

    在进行测试的时候,经常需要对数据库进行操作.我们知道,通过代码与数据库交互,需要以下几步: 1.加载驱动 之前有盆友问我,为什么Selenium操作浏览器的时候,非要下载浏览器驱动?为啥对数据库进行操 ...

  2. lua敏感词过滤

    --过滤敏感词(如果onlyKnowHas为true,表示只想知道是否存在敏感词,不会返回过滤后的敏感词,比如用户注册的时候,我们程序是只想知道用户取的姓名是否包含敏感词的(这样也能提高效率,检测到有 ...

  3. LeetCode 82 ——删除排序链表中的重复元素 II

    1. 题目 2. 解答 新建一个链表,并添加一个哨兵结点,从前向后开始遍历链表. 如果下一个结点的值和当前结点的值相等,则循环向后遍历直到找到一个和当前结点值不相等的结点: 反之,如果下一个结点的值和 ...

  4. React错误总结(三)

    神坑react native之Cannot Add a child that doesn't have a YogaNode to a parent with out a measure functi ...

  5. HDU 4757 Tree(可持久化字典树)(2013 ACM/ICPC Asia Regional Nanjing Online)

    Problem Description   Zero and One are good friends who always have fun with each other. This time, ...

  6. 并查集——poj1308(并查集延伸)

    题目链接:Is It A Tree? 题意:给你一系列形如u v的点对(u v代表一条由u指向v的有向边),请问由给你的点构成的图是不是一棵树? 树的特征:①每个节点(除了根结点)只有一个入度:②只有 ...

  7. 文件系统之 stat与access

    stat命令 stat既有命令也有同名函数,用来获取文件Inode里主要信息,所以stat命令的输出信息比ls命令的输出信息要更详细,stat 跟踪符号链接,lstat不跟踪符号链接,其中会输出对应文 ...

  8. MvcMusicStore学习中常出现的一个BUG

    BUG描述:var genreModel = storeDB.Genres.Include("Albums").Single(g => g.Name == genre); 前 ...

  9. windows redis+lua的调试

    1.编写lua脚本my.lua local key = KEYS[1] --限流KEY(一秒一个) local limit = tonumber(ARGV[1]) --限流大小 local curre ...

  10. 【版本控制】VisualSVN Server更改SVN版本库存放路径的方法

    最近也玩起了SVN软件版本管理,在本机上安装了VisualSVN Server+TortoiseSVN,感觉还不错吧.但是,版本库存在哪里呢?在安装VisualSVN Server时,已经默认设置了, ...