codeforces 985C3 Encryption (hard)

本文探讨了解决大规模数据下求最小值问题的一种高效算法。通过动态规划(DP)结合树状数组进行维度压缩,实现对复杂度的有效优化。文章详细介绍了如何利用两个树状数组分别维护小于和大于特定值的前缀和,从而快速计算最优解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

跟前面的两道题不同的就是数据变大了,并且变成了求最小值,首先考虑dp

设f[i][j]表示前i个位置里分了j份的最小值。sum[i]表示到i为止val[i]的和 mod p的值。

f[i][j]=max(f[k][j-1]+(sum[i]-sum[k]) \ mod \ p)(1\leqslant i\leqslant n,1\leqslant k< i , 1\leqslant j\leqslant K)

但是这样会超时,所以考虑优化掉一维,对于式子分析,可以发现后面的 mod p有两种情况,拆开式子分别为

sum[i]\geqslant sum[k]

f[i][j]=max(f[k][j-1]-sum[k]+sum[i] )

sum[i]<sum[k]

f[i][j]=max(f[k][j-1]-sum[k]+p+sum[i])

这个可以用两个树状数组维护,每次dp的时候,

当前的j可以由≤s[i]的第一个树状数组和>s[i]的第二个树状数组的最小值加上自己的s[i]。

设树状数组c[0/1][pos][vv],pos表示j的位置,vv表示小于或者大于s[i],因为第二个树状数组需要大于s[i]的和,就是后缀和

所以将[i]变为p-s[i]改为求前缀和。

还有解释在代码里

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int n,k,p,dp[105],val[500005],s[500005],c[2][105][105];
int lowbit(int x)
{
	return x&(-x);
}
void add(int ops,int pos,int xb,int v)
{
	xb++;//因为有0。 
	while(xb<=p+1)//范围为0~p,因为有两种,s[i],p-s[i]。 
	{
		c[ops][pos][xb]=min(c[ops][pos][xb],v);
		xb+=lowbit(xb);
	}
}
int query(int ops,int pos,int xb)
{
	int ret=0x3f3f3f3f;xb++;
	while(xb)
	{
		ret=min(ret,c[ops][pos][xb]);
		xb-=lowbit(xb);
	}
	return ret;
}
int main()
{
	scanf("%d%d%d",&n,&k,&p);
	for(int i=1;i<=n;i++)scanf("%d",&val[i]),s[i]=(s[i-1]+val[i])%p;
	for(int i=1;i<=k;i++)
	{
		for(int j=0;j<=p+1;j++)
		{
			c[0][i][j]=c[1][i][j]=0x3f3f3f3f;
		}
	}
	add(0,0,0,0);//这行没啥用 
	add(1,0,0,0);//这两行相当于初值。 
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=min(j,k);j++)
		{
			dp[j]=min(query(0,j-1,s[i]),query(1,j-1,p-s[i]))+s[i];//当前j更新可以从前面所有i。所以下标是这样的,因为要求前缀和,而另一种需要后缀,所以这样 
		}
		for(int j=1;j<=min(i,k);j++)
		{
			if(dp[j]==0x3f3f3f3f)continue;
			add(0,j,s[i],dp[j]-s[i]);
			add(1,j,p-s[i],dp[j]-s[i]+p);
		}
	}
	printf("%d\n",dp[k]);
	return 0;
}

 

资源下载链接为: https://pan.quark.cn/s/67c535f75d4c 在机器人技术中,轨迹规划是实现机器人从一个位置平稳高效移动到另一个位置的核心环节。本资源提供了一套基于 MATLAB 的机器人轨迹规划程序,涵盖了关节空间和笛卡尔空间两种规划方式。MATLAB 是一种强大的数值计算与可视化工具,凭借其灵活易用的特点,常被用于机器人控制算法的开发与仿真。 关节空间轨迹规划主要关注机器人各关节角度的变化,生成从初始配置到目标配置的连续路径。其关键知识点包括: 关节变量:指机器人各关节的旋转角度或伸缩长度。 运动学逆解:通过数学方法从末端执行器的目标位置反推关节变量。 路径平滑:确保关节变量轨迹连续且无抖动,常用方法有 S 型曲线拟合、多项式插值等。 速度和加速度限制:考虑关节的实际物理限制,确保轨迹在允许的动态范围内。 碰撞避免:在规划过程中避免关节与其他物体发生碰撞。 笛卡尔空间轨迹规划直接处理机器人末端执行器在工作空间中的位置和姿态变化,涉及以下内容: 工作空间:机器人可到达的所有三维空间点的集合。 路径规划:在工作空间中找到一条从起点到终点的无碰撞路径。 障碍物表示:采用二维或三维网格、Voronoi 图、Octree 等数据结构表示工作空间中的障碍物。 轨迹生成:通过样条曲线、直线插值等方法生成平滑路径。 实时更新:在规划过程中实时检测并避开新出现的障碍物。 在 MATLAB 中实现上述规划方法,可以借助其内置函数和工具箱: 优化工具箱:用于解决运动学逆解和路径规划中的优化问题。 Simulink:可视化建模环境,适合构建和仿真复杂的控制系统。 ODE 求解器:如 ode45,用于求解机器人动力学方程和轨迹执行过程中的运动学问题。 在实际应用中,通常会结合关节空间和笛卡尔空间的规划方法。先在关节空间生成平滑轨迹,再通过运动学正解将关节轨迹转换为笛卡
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值