当前位置: 首页 > news >正文

第九届中国大学生程序设计竞赛(秦皇岛)-(CCPC2023-Qinhuangdao F - 质数之谜(DP)

题意

给定一个序列,修改最少数量的元素使得任意i属于[1,n-1],q[i]+q[i+1]都为质数,输出最小修改次数

思路


首先手玩的过程中可以发现,
    如果因为前面一个数字和自己相加不是质数然后我把自己变成了奇数,那么如果我后面一个数字是偶数
    可以发现自己肯定能找到另一个奇数使得和前面相加互质并且和后面相加也互质
    举个例子:假设为2 8 10,我此时是8,我发现2+8不是质数把自己改为5,但是5+10不是质数,但是无论如何我都可以找到一个数字(因为这个数字没有范围限制)x,使得x+2和x+10都是质数,这个样例中取x=3即可
由于前面的修改会影响后面的修改,所以考虑用线性DP来写
然后由发现的结论可以知道,假设前面的一个数字已经被修改过并且改为奇数,那么如果此时位置的数为偶数,那么前面一个数字一定能再找到一个奇数(还是相当于只修改一次)使得这个偶数和奇数互质
但是由于1(奇数)+1(奇数)奇偶性相同但是也满足结论,所以变1这个情况要特判

那么dp有4个状态,0:不变 1:变偶数 2:变奇数(非1) 3:变1

只要考虑每个状态可以由什么状态转移过来就可以解决这个问题

f[i-1][0]:如果原数组前后两个数互质时候(!st[q[i-1]+q[i]) 
f[i-1][1]:如果q[i]为奇数,并且前一个变成了偶数也就是f[i-1][1]
f[i-1][2]:如果q[i]为偶数,并且前一个变成了奇数也就是f[i-1][2]
f[i-1][3]:如果q[i]+1为质数
----->可以转移给f[i][0]状态

f[i-1][0]:q[i-1]为奇数的时候
f[i-1][1]:如论如何都不能转移
f[i-1][2]:一定可以转移
f[i-1][3]:一定可以转移
----->可以转移给f[i][1]状态
        
f[i-1][0]:q[i-1]为偶数的时候
f[i-1][1]:一定可以转移
f[i-1][2]:如论如何都不能转移
f[i-1][3]:如论如何都不能转移
----->可以转移给f[i][2]状态
        
f[i-1][0]:q[i-1]+1为奇数的时候
f[i-1][1]:一定可以转移
f[i-1][2]:如论如何都不能转移
f[i-1][3]:q[i-1]不等于1的时候(因为等于就不是变成1的情况了)可以转移
----->可以转移给f[i][3]状态
*/

代码实现

#include <map>
#include <set>
#include <queue>
#include <deque>
#include <cmath>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define pp pop_back()
#define int long long
#define laile cout<<"laile"<<endl
#define lowbit(x) ((x)&(-x))
#define double long double
#define sf(x) scanf("%lld",&x)
#define sff(x,y) scanf("%lld %lld",&x,&y)
#define sd(x) scanf("%Lf",&x)
#define sdd(x,y) scanf("%Lf %Lf",&x,&y)
#define _for(i,n) for(int i=0;i<(n);++i)
#define _rep(i,a,b) for(int i=(a);i<=(b);++i)
#define _pre(i,a,b) for(int i=(a);i>=(b);--i)
#define all(x) (x).begin(), (x).end()
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
typedef unsigned long long ULL;
typedef pair<int,int>PII;
const int N=1e6+10,INF=4e18;
int n,m;
int q[N];
int f[N][5];
int prime[N],cnt;
bool st[N];
//0不变 1变偶 2变奇 3变1
void init()
{for(int i=2;i<=200000;i++){if(!st[i])prime[cnt++]=i;for(int j=0;prime[j]*i<=200000;j++){st[prime[j]*i]=true;if(i%prime[j]==0)break;}}return;
}
void solve()
{cin>>n;_rep(i,1,n)cin>>q[i];memset(f,0x3f,sizeof(f));f[1][0]=0;f[1][1]=f[1][2]=f[1][3]=1;_rep(i,2,n){//0if(!st[q[i]+q[i-1]])f[i][0]=min(f[i][0],f[i-1][0]);if(q[i]%2)f[i][0]=min(f[i][0],f[i-1][1]);else f[i][0]=min(f[i][0],f[i-1][2]);if(!st[q[i]+1])f[i][0]=min(f[i][0],f[i-1][3]);//1,2if(q[i-1]%2)f[i][1]=min(f[i][1],f[i-1][0]+1);else f[i][2]=min(f[i][2],f[i-1][0]+1);f[i][1]=min(f[i][1],f[i-1][2]+1);f[i][1]=min(f[i][1],f[i-1][3]+1);f[i][2]=min(f[i][2],f[i-1][1]+1);//3if(!st[q[i-1]+1]&&q[i]!=1)f[i][3]=min(f[i][3],f[i-1][0]+1);f[i][3]=min(f[i][3],f[i-1][1]+1);if(q[i-1]!=1)f[i][3]=min(f[i][3],f[i-1][3]+1);}int res=INF;
//测试
//    for(int i=1;i<=n;i++)
//    {
//        int now=INF;
//        for(int j=0;j<=3;j++)
//        {
//            if(f[i][j]!=0x3f3f3f3f3f3f3f3f)
//            cout<<f[i][j]<<" ";
//            else cout<<"- ";
//        }
//        cout<<endl;
//    }_rep(i,0,3)res=min(res,f[n][i]);cout<<res<<"\n";return ;
}
signed main()
{IOS;int T=1;init();
//    cin>>T;while(T--)solve();return 0;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 谈谈nvm、nrm、pnpm的理解
  • FPGA速度优化
  • 新手该如何选择与小程序定位相关的关键词
  • Yolo环境搭建(深度学习基础环境)
  • 利用优先级队列的堆排序练习
  • visual studio 2005 ( vs2005 , vc2005 ) 编译的应用程序无法运行的解决方案
  • 与PC1显著相关的基因 | p值计算
  • 个人旅游网(1)——数据库表详解
  • JVM1-初识JVM
  • 【cocos creator】养成游戏简易事件系统,每日随机事件,每日行动点重置,根据数据检测多结局
  • 【Unity输入】Input Manager 和 Input System对比
  • 实训第三十二天(学习playbook-roles,脚本创建数据库和表,mycat读写分离)
  • 2024年程序员金九银十面试宝典持续更新中.....
  • 【Spring Boot 3】【Web】同时启用 HTTP 和 HTTPS
  • 命令模式与宏命令:批量操作的高效实现
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • android百种动画侧滑库、步骤视图、TextView效果、社交、搜房、K线图等源码
  • Asm.js的简单介绍
  • HomeBrew常规使用教程
  • iBatis和MyBatis在使用ResultMap对应关系时的区别
  • idea + plantuml 画流程图
  • Idea+maven+scala构建包并在spark on yarn 运行
  • maven工程打包jar以及java jar命令的classpath使用
  • MD5加密原理解析及OC版原理实现
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • node 版本过低
  • php面试题 汇集2
  • python学习笔记-类对象的信息
  • Selenium实战教程系列(二)---元素定位
  • 工作中总结前端开发流程--vue项目
  • 聊聊flink的BlobWriter
  • 浅谈Golang中select的用法
  • 听说你叫Java(二)–Servlet请求
  • 智能合约开发环境搭建及Hello World合约
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • ‌U盘闪一下就没了?‌如何有效恢复数据
  • # Redis 入门到精通(八)-- 服务器配置-redis.conf配置与高级数据类型
  • #pragma 指令
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • #我与Java虚拟机的故事#连载18:JAVA成长之路
  • $.proxy和$.extend
  • $nextTick的使用场景介绍
  • (1)(1.11) SiK Radio v2(一)
  • (1)无线电失控保护(二)
  • (3)llvm ir转换过程
  • (C#)一个最简单的链表类
  • (javascript)再说document.body.scrollTop的使用问题
  • (javaweb)Http协议
  • (php伪随机数生成)[GWCTF 2019]枯燥的抽奖
  • (ZT)北大教授朱青生给学生的一封信:大学,更是一个科学的保证
  • (全注解开发)学习Spring-MVC的第三天
  • (十六)一篇文章学会Java的常用API
  • (未解决)jmeter报错之“请在微信客户端打开链接”
  • (转)母版页和相对路径
  • (轉貼) 寄發紅帖基本原則(教育部禮儀司頒布) (雜項)