P4933 大师(DP)
题意:给定序列求所有子序列中为等差数列的个数。(序列长度为1,2被认为是等差序列,空序列不是等差序列)。
思路:很巧妙的,因为,数字较小。所以考虑设表示以下标的数字结尾公差为的等差序列个数。因为公差可能为负,所以整体向右移动位。
状态转移方程:.
这个是当两个数组成的等差序列。因为开始一个数的等差序列我们可以预处理就是了。所以里面是不含一个数等差序列,所以递推时要加上1.
还有一个注意的问题,因为我们不知道每个等差序列的公差是多少,所以我们在递推的时候一边递推,一边要加上贡献。
时间复杂度:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e3+5,M=4e4+5,mod=998244353; #define mst(a) memset(a,0,sizeof a) #define lx x<<1 #define rx x<<1|1 #define reg register #define PII pair<int,int> #define fi first #define se second inline void read(int &x){ x=0;int w=1; char ch=getchar(); while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();} for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch&15); x*=w; } int h[N],dp[N][M],n; int main(){ read(n); for(int i=1;i<=n;i++) read(h[i]); ll ans=0; int p=2e4; for(int i=1;i<=n;i++){ ans++; for(int j=i-1;j>=1;j--){ dp[i][h[i]-h[j]+p]=(dp[i][h[i]-h[j]+p]+dp[j][h[i]-h[j]+p]+1)%mod; ans=(ans+dp[j][h[i]-h[j]+p]+1)%mod; } } printf("%lld\n",ans); return 0; }