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;
}
posted @ 2011-07-19 23:36  zqynux  阅读(309)  评论(0编辑  收藏  举报