备战蓝桥杯---动态规划(应用3之空间优化)

话不多说,直接看题:

我们不妨把问题抽象一下:

首先,我们由裴蜀定理知道如果两个数互质,那么ax+by=c一定有整数解(只要c为1的倍数也就是整数),因此问题就转换为求选一些数使他们gcd==1(对1特判)

考虑到与背包问题的类似性,于是我们令fij为前i个数gcd==j的最小花费。

于是我们得到转移方程:fij=min(fi-1j,fi-1k+ci)(k与li的gcd==j)

但是我们注意一下范围k显然不能遍历到10^9,注意到我们遍历的为gcd,而这个远小于li,因此我们可以用map来优化空间(存可能的gcd),每一轮的gcd在循环时直接推出即可。

下面为AC代码:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#define ma 10000000
#define int long long
int n,l[310],c[310],cnt;
map<int,int> a[310];
int _gcd(int a,int b){
	while(b){
		int tmp=b;
		b=a%b;
		a=tmp;
	}
	return a;
}
struct node{
	int dian,zhi;
};
queue<int> q;
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++) scanf("%lld",&l[i]);
	for(int i=1;i<=n;i++) scanf("%d",&c[i]);
	int ans=ma;
	for(int i=1;i<=n;i++){
		if(a[i].count(l[i])==0) a[i][l[i]]=c[i];
		else a[i][l[i]]=min(c[i],a[i][l[i]]);
		map<int,int>::iterator it;
		for(it=a[i-1].begin();it!=a[i-1].end();it++){
			if(a[i].count(it->first)==0) a[i][it->first]=a[i-1][it->first];
			else a[i][it->first]=min(a[i-1][it->first],a[i][it->first]);
		}
		for(it=a[i-1].begin();it!=a[i-1].end();it++){
			if(a[i].count(_gcd(it->first,l[i]))==0) a[i][_gcd(it->first,l[i])]=a[i-1][it->first]+c[i];
			else a[i][_gcd(it->first,l[i])]=min(a[i-1][it->first]+c[i],a[i][_gcd(it->first,l[i])]);
		}
		if(a[i].count(1)!=0) ans=min(ans,a[i][1]);
	}
	if(ans>=ma) cout<<-1;
	else cout<<ans;
} 

接题:

我们直接令fij表示到i的位置时所跳的距离j时得到的最大值。

转移方程为:

fij=pi+max(fi-jj,fi-jj-1,fi-jj+1).

但是当d=30000时空间就不够了。

我们不妨计算1+...+n<=30000,发现最大的波动范围最多(-250--250)

因此,我们不妨让j的位置存波动值即可。(注意判断范围)

下面是AC代码:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#define ck 250
int n,d,dp[30001][502],a[30010],x,max1;
int main(){
	cin>>n>>d;
	for(int i=1;i<=n;i++){
		scanf("%d",&x);
		a[x]++;
		max1=max(x,max1);
	}
	memset(dp,-0x3f,sizeof(dp));
	dp[d][ck]=a[d];
	int ans=a[d];
	for(int i=1+d;i<=max1;i++){
		for(int j=0;j<=500;j++){
			int x1=d+j-ck;
			if(i-x1<=0) continue;
			if(x1<=0) continue;
			for(int k=-1;k<=1;k++){
				if(j+k>0) dp[i][j]=max(dp[i][j],dp[i-x1][j+k]+a[i]);
			}
			ans=max(ans,dp[i][j]);
		}
	}
	cout<<ans;
}
相关推荐
徐小夕8 小时前
花了3个月,我们做了一款 AI 版的“飞书文档”
前端·算法·github
Robert--cao8 小时前
移动底盘与机械臂联合规划:开源算法与工程实现
算法
小豆庄9 小时前
Mac 上给视频人脸打码:本地工具的依赖、追踪与推理管线
算法·视觉检测·视频·敏捷流程·纹理贴图
星夜离尘569 小时前
MATLAB 工程实验:从相邻块均值手写重叠 Allan 偏差,数清有效项
算法·matlab·均值算法
y1su11 小时前
Leetcode 字符串模板
java·数据结构·算法·leetcode·职场和发展·动态规划
residual_fan11 小时前
船用柴油机动态机动工况故障诊断:控制感知仿射网络(CAAN)的技术实现
人工智能·算法·数据挖掘·数据分析
syagain_zsx12 小时前
BRpc 二次封装:Channel 管理、服务管理与回调工厂
c++·学习·程序人生·rpc·谷歌
其实防守也摸鱼12 小时前
Cylab在线靶场——CTF中的通用技能
linux·数据库·学习·算法·靶场·ctf·学习网络安全
蓝悦无人机12 小时前
《Planning algorithms》读书笔记——第8章 反馈运动规划
算法·读书笔记·反馈运动规划
RaaS10013 小时前
Agent Skills 进了 Linux Foundation:2.8 亿次安装,但装 skill 还没有安全规范
人工智能·算法·架构