线性dp

题目背景
建筑大师最近在跟着数学大师 ljt12138 学数学,今天他学了等差数列,ljt12138 决定给他留一道练习题。

题目描述
ljt12138 首先建了 nn 个特斯拉电磁塔,这些电塔排成一排,从左到右依次标号为 11 到 nn ,第 ii 个电塔的高度为 h[i]h[i] 。

建筑大师需要从中选出一些电塔,然后这些电塔就会缩到地下去。这时候,如果留在地上的电塔的高度,从左向右构成了一个等差数列,那么这个选择方案就会被认为是美观的。

建筑大师需要求出,一共有多少种美观的选择方案,答案模 998244353998244353 。

注意,如果地上只留了一个或者两个电塔,那么这种方案也是美观的。地上没有电塔的方案被认为是不美观的。

同时也要注意,等差数列的公差也可以为负数。

输入格式
第一行一个正整数 nn 。

第二行 nn 个非负整数,第 ii 个整数是第 ii 个电塔的高度 h[i]h[i] 。

输出格式
输出一个整数,表示美观的方案数模 998244353998244353 的值。

这题我觉得还是特别难的,要想到动态规划f数组定义为以i结尾,公差为j的等差数列的方案数,如果定义成只考虑前i个就很难转移,想想转移的复杂度,如果枚举ijk n^2v必定超时,我们发现 当只有a[i]-a[j]==k时才会转移,我们可以优化一下 只枚举 i和j,然后想想如何转移
我们以i结尾的前一个数j当作划分依据,我一开始以为是f[i][a[i]-a[j]+maxh]+=f[j][a[i]-a[j]+maxh] 结果发现是不对的 ,因为a[j]和a[i]这两个也可以组成等差数列且公差是ai-aj ,那么就应该是f[i][a[i]-a[j]+maxh]+=f[j][a[i]-a[j]+maxh]+1了,注意坑点,公差可以是负数,那么我们加一个最大值作为偏移量,防止越界。
ac代码:

#include<iostream>
#include<cstring>
#include<map>
#include<vector>
#include<cmath>
#include<algorithm>
#include<set>
#define x first
#define y second
using namespace std;
typedef long long ll;
const int N=1010;
const int M=40010;
typedef pair<int,int> pii;
int a[N];
int f[N][M];	//考虑前i个包括第i个 公差为d的方案数
const int mod=998244353;
int n;
int main()
{
   
	// 2 2 4
	// f[1][2]=0;
	// f[2][2]=0;
	// f[4][2]=2;
	// 3 5 7 9
	// 3 5 7 9
	// 3 5 
	// f[2][1]=1
	// f[3][1]=2
	//f[i][k]
	cin >> n; 
	int maxh=0;
	for(int i=1;i<=n;i++)
		cin>>a[i] , maxh=max(maxh,a[i]);
	//cout<<maxh<<endl;
	for(int i=1;i<=n;i++)
		f[i][0]=1;
	int res=0;
	for(int i=1;i<=n;i++)
		{
   
			for(int j=1;j<i;j++)
				{
   
					f[i][a[i]-a[j]+maxh]= (f[i][a[i]-a[j]+maxh] + 1 +f[j][a[i]-a[j]+maxh])%mod; 	
					
				}
			for(int j=0;j<M;j++)
			res=(res+f[i][j])%mod;	
			}

	cout<<res<<endl;
	return 0;
}
全部评论

相关推荐

03-27 16:40
已编辑
门头沟学院 C++
26学院本太难了,很多公司机筛就给我刷了。机会都难拿到如果是简历存在问题也欢迎拷打————————————————————分割线——————————————————————2026.3.4更新:发完贴之后,时不时投递又收到了不少的笔试/面试邀请。主要是之前投递简历出去之后基本上都是沉默状态,年后好转了不少timeline:2026.01.21&nbsp;文远知行笔试,半年多没刷算法题&nbsp;-&gt;挂&nbsp;(后续HR说春招可以重新安排笔试)2026.2.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;小鹏汇天&nbsp;技术一面,第二周收到结果&nbsp;-&gt;挂2026.2.12&nbsp;&nbsp;&nbsp;大众Cariad代招&nbsp;技术二面&nbsp;-&gt;Offer2026.2.28&nbsp;&nbsp;&nbsp;多益网络技术面试,由于风评太差,一直在犹豫要不要接面试&nbsp;-&gt;推迟-----------分割线-----------2026.3&nbsp;月前的某一天,临时去电网报名了二批计算机岗位的笔试2026.3.6&nbsp;从上家公司实习离职,氛围最好的一家公司,leader&nbsp;说可以帮忙转正,但是流程太长,而且我们部门据说只有一个&nbsp;hc,更想要研究生,我很有可能是会被签外包公司在这里干活,就离职了。2026.3.9&nbsp;入职新公司,大众Cariad&nbsp;以外部公司的身份进组,项目组签了三年,后续三年应该都可以在这里呆,不知道有没有希望原地跳槽。2026.3.10&nbsp;电网考试居然说我通过资格审查了,短信约我去参加资格审查,请假一天,买了&nbsp;12&nbsp;号晚上的机票回成都2026.3.15&nbsp;参加国家电网计算机类笔试2026.3.17&nbsp;电网出成绩了,感觉很低。觉得已经🈚️了2026.3.18&nbsp;收到电网面试通知,通知&nbsp;3.22-3.25&nbsp;这个时间去面试,我的岗位只招&nbsp;1&nbsp;个人。据说面试只有&nbsp;2-3&nbsp;人,不知道能不能成功----------分割线-----------2026.3.21&nbsp;电网面试结束,感觉回答的还勉勉强强,大概是2个岗位分别招1个人,一共11人面试,实际来了9人2026.3.27&nbsp;出面试成绩,满分100分,早上10:20左右发现面试成绩46,我震惊了,没截图,后面过了十分钟重新看发现面试成绩给我改成58了。但同样震惊。朋友问我是不是把面试官打了,哈哈
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
正在热议
更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务