题目链接:P4933 大师
一道不怎么套路的 (dp),所以就没做出来/kk/dk。
我们记 (dp[i][j]) 为以 (i) 为首项,(j) 为公差的等差数列个数。
考虑倒推。
当 (l,r) 的差为 (k)时,容易知道:
[dp[l][k]=dp[r][k]+1
]
为啥?
情况一:在原来的等差数列前加一个数;
情况二:构造一个长为 (2) 的等差数列,两项分别为 (l,r)。
最后答案的统计。
只要出现一个,就加上。
(Code:)
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
#define read(x) scanf("%d",&x)
#define MAXN 200005
#define MOD 998244353
int n,h[1005];
int dp[1005][MAXN<<1];
int ans=0;
int main()
{
read(n);
for(int i=1;i<=n;i++) read(h[i]);
for(int i=n-1;i>=1;i--)
{
for(int j=i+1;j<=n;j++)
{
dp[i][h[j]-h[i]+MAXN]=(dp[i][h[j]-h[i]+MAXN]+dp[j][h[j]-h[i]+MAXN]+1)%MOD;
ans=(ans+dp[j][h[j]-h[i]+MAXN]+1)%MOD;
}
}
printf("%d
",(ans+n)%MOD);
return 0;
}