TYVJ 1091 等差数列 解题报告
好题!第一,不好理解,考验!第二,锻炼了我使用C的负数坐下标的能力。
题目是个DP,f[i][j]代表以j开头的,长度为i的等差序列的数目,最后要输出的时f[i][j](-1000<=i<=1000, 0 <= j < n)(我用的C, 所以j是[0, n)。)
转移方程是:f[num[i] - num[j]][i] = f[num[i] - num[j]][i] + f[num[i] - num[j]][j] + {1}如果num[i] - num[j]不等于0就加一,代码如下:
#include <stdio.h> #include <stdlib.h> int num[1000]; int f_[2001][1000]; int (*f)[1000]; //f[i][j]代表以j最后一项, i为长度的等差序列的数目 int ans; int main(int argc, char **argv) { int i, j, k; int n; f = &f_[1000]; scanf("%d", &n); for(i = 0; i < n; i++){ scanf("%d", &num[i]); } for(i = 0; i < n; i++){ f[0][i] = 1; } for(i = 0; i < n; i++){ for(j = i - 1; j >= 0; j--){ k = num[i] - num[j]; f[k][i] = f[k][i] + f[k][j]; if(k != 0){ f[k][i]++; } } } for(i = -1000; i <= 1000; i++){ for(j = 0; j < n; j++){ ans = (ans + f[i][j]) % 9901; } } printf("%d\n", ans); return 0; }