求解回文序列问题
【问题描述】
如果一个数字序列逆置后跟原序列是一样的,则称这样的数字序列为回文序列。
例如:{1,2,1}、{15,78,78,15}、{11,2,11}是回文序列,而{1,2,2}、{15,78,87,51}、{112,2,11}不是回文序列。
现在给出一个数字序列,允许使用一种转换操作:选择任意两个相邻的数,然后从序列中移除这两个数,并将这两个数的和插入到这两个数之前的位置(只插入一个和)。
对于所给的序列求出至少需要多少次操作可以将其变成回文序列。
输入描述:输入为两行,第一行为序列长度n(1<=n<=50),第二行为序列中的n个整数item[i](1<=item[i]<=1000),以空格分隔。
输出描述:输出一个数,表示最少需要的转换次数。
输入样例:
4
1 1 1 3
样例输出
2
【思路】
这样的问题采用递归调用比较简单,而递归的核心思想:大问题转换为小问题加上特殊出口。
对输入的数组进行第一个数和最后一个数同时扫描,如果相等,跳过两个数的处理,第一位向后移动一位,最后一位向前移动一位。若不相等,第一种情况:第一位小于最后一位,则将第一位与它后一位相加为一个数,记录一次操作,进入递归。第二种情况:第一位大于最后一位:将最后一位与它前一位相加为一个数,记录一次操作,进入递归。
当前面扫描与后面扫描相遇时停止递归(特殊出口)。
【代码】
1 #include<stdio.h> 2 int hui(int a[],int n,int i,int j,int t) 3 { 4 if(i>=j)return(t); 5 else if(a[i]==a[j])hui(a,n,i+1,j-1,t); 6 else if(a[i]<a[j]) 7 { 8 a[i]+=a[i+1]; 9 int k; 10 for(k=i+1;k<n;k++) 11 { 12 a[k]=a[k+1]; 13 } 14 hui(a,n-1,i,j-1,t+1); 15 } 16 else if(a[i]>a[j]) 17 { 18 a[j-1]+=a[j]; 19 int k; 20 for(k=j;k<n;k++) 21 { 22 a[k]==a[k+1]; 23 } 24 hui(a,n-1,i,j-1,t+1); 25 } 26 } 27 28 int main() 29 { 30 int n; 31 printf("序列个数:"); 32 scanf("%d",&n); 33 int a[n]; 34 int k; 35 printf("输入序列:"); 36 for(k=0;k<n;k++) 37 { 38 scanf("%d",&a[k]); 39 } 40 printf("次数:%d",hui(a,n,0,n-1,0)); 41 return 0; 42 }
【示例】