数组子序列的个数,比如4,14,2,3和14,1,2,3都为4,13,14,1,2,3的子序列。 对于给出序列a,有些子序列可能是相同的,这里只算做1个,要求输出a的不同子序列的数量。
分析:如果对一个数组后面添加一个与前面都不同的数字构成一个新的数组,那么新的数组的子序列就是前面的子序列的个数乘以2,再加上新添加的数字;如果后面添加的数字前面出现过,那么按照上面的计算方式中存在重复的,将重复的剪掉即可:一个是自身,一个是离自身最近的与自身形同的数字对应的子序列数,比如1,2,3,4,5,6,4,7,8,4;那么就应该减去1,2,3,4,5,6,4这段所有的子序列;因为1,2,3,4,5,6与后面第一个4可以形成的序列与最后一个4也可以形成;
代码如下:
// [10/2/2013 qingezha] 数组子序列的个数,4,14,2,3和14,1,2,3都为4,13,14,1,2,3的子序列。 对于给出序列a,有些子序列可能是相同的,这里只算做1个,要求输出a的不同子序列的数量。
// 用一个数组记录出现2次或2次以上的数字,离当前数字最近的相同的数字的下标
// 比如1 2 3 4 2,一开始都为0,然后下标一次变为1 2 3 4,到新2 的时候 因为有2,所以要找到这个2的下标,才可以运算那个式子
// 所以用last_index记录数字的下标,里面是对应的arr[i],即要找的值2
#define Mod 1000000007
long sub_sequence(int *arr,int len)
{
long sub_arr[120] = {0};
int last_index[120] = {0}; //初始值这里设的好
for (int iter=1;iter<=len;++iter)
{
switch(last_index[arr[iter-1]])
{
case 0:
{
sub_arr[iter] = 2 * sub_arr[iter-1]+ 1;
break;
}
default:
{
sub_arr[iter] = 2 * sub_arr[iter-1] - sub_arr[last_index[arr[iter-1]]-1];//上一个相同的数字的下标
}
}
last_index[arr[iter-1]] = iter; //这里写错了last_index[iter-1],每一次都更新,按次序递增
}
return sub_arr[len]; //这里写错了 sub_arr[len-1]
//test///
//int arr[20] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
//cout<<sub_sequence(arr,sizeof(arr)/sizeof(int));
//
}