描述 Description
等差数列的定义是一个数列S,它满足了(S[i]-S[i-1]) = d (i>1)。显然的一个单独的数字或者两个数字也可以形成一个等差数列。经过一定的学习小C发现这个问题太简单了,等差数列的和不就是(Sn+S1)*n/2?因为这个问题实在是太简单了,小C不屑于去解决它。这让小C的老师愤怒了,他就找了另外一个问题来问他。
小C的老师给了他一个长度为N的数字序列,每个位置有一个整数,他需要小C帮他找到这个数字序列里面有多少个等差数列。
……
这个问题似乎太难了,小C需要你的程序帮他来解决这个问题。
输入格式 InputFormat
第一行一个整数N,表示老师给出的数字序列的长度。第二行有N个整数A[i],表示数字序列每个数字的大小。
输出格式 OutputFormat
输出只有一行一个整数,表示这个序列中的等差数列的个数(mod 9901)。样例输入 SampleInput
5 1 4 2 3 7
样例输出 SampleOutput
17
数据范围和注释 Hint
对于30%的数据,N <= 100对于70%的数据,N <= 500
对于100%的数据,N <= 1000;-500 <= A[i] <= 500
思路:
动态规划,dp[i][j]: 以第i个数结束,等差为j-1000的等差
数列长度(默认两个数形成的数列长度为1,只加了一个
等差)(因为j为正,但等差有可能为负, 所以以j = 100
0表示等差为0)。
#include <stdio.h>
#include <string.h>
int dp[1001][2001], data[1001];
int main()
{
int n, i, j, cnt;
scanf("%d", &n);
for(i = 0; i < n; i++)
{
scanf("%d", &data[i]);
}
memset(dp, 0, sizeof(dp));
cnt = 0;
for(i = 1; i < n; i++)
{
for(j = 0; j < i; j++)
{
dp[i][data[i]-data[j]+1000] += (dp[j][data[i]-data[j]+1000]+1); //增长后的长度
cnt = (cnt+(dp[j][data[i]-data[j]+1000]+1))%9901; //长度每加1, 递增序列数量加上新长度等值数量, 例如1234,当j=1,i指向3时cnt应加3,数列分别为1~4,2~4,3~4.
}
}
printf("%d\n", cnt+n); //结果加上一个一组的数量(题意)
return 0;
}