题目:
如果一个数字序列逆置之后跟原序列是一样的就称这样的数字序列为回文序列。例如:{1, 2, 1}, {15, 78, 78, 15} , {112} 是回文序列, {1, 2, 2}, {15, 78, 87, 51} ,{112, 2, 11} 不是回文序列。现在给出一个数字序列,允许使用一种转换操作:选择任意两个相邻的数,然后从序列移除这两个数,并用这两个数字的和插入到这两个数之前的位置(只插入一个和)。
对于所给序列要求出最少需要多少次操作可以将其变成回文序列。
输入
输入为两行,第一行为序列长度n ( 1 ≤ n ≤ 50),第二行为序列中的n个整数item[i] (1 ≤ iteam[i] ≤ 1000),以空格分隔。
输出
输出一个数,表示最少需要的转换次数
样例输入
4
1 1 1 3
样例输出
2
#include<iostream>
using namespace std;
const int N = 55;
int cnt,min_step = 0x3f3f3f3f;
int a[N];
int n;
bool check(int k,int temp_check[])//判断是否回文串
{
for(int i = 0; i < k; i++)
if(temp_check[k - i - 1] != temp_check[i]) return false;
return true;
}
bool dfs(int k,int a1[],int num)
{
int temp[N];
if(k == 0) return false;
if(check(k,a1))
{
min_step = min(min_step,num);//选择最小的
return true;
}
for(int i = 0; i < k - 1; i ++)//选择哪一对 当前的数
{
int sum = a1[i] + a1[i+1];//选择第i和第i+1个 加为和
int u = 0;
for(int j = 0 ; j < k; j++)//把当前的情况放进到temp数组里面
{
if(i == j)//如果遍历到了i的位置,就把和放进去
temp[u++] = sum;
else if(j == i+1) continue;//如果到了i+1,那么k++;
else temp[u++] = a1[j];
}
num ++;
dfs(u,temp,num);
num --;
}
}
int main()
{
cin>>n;
cnt = n-1;
for(int i = 0; i < n; i++)
cin>>a[i];
dfs(n,a,0);
cout<<min_step<<endl;
return 0;
}