回文序列-2017网易校园招聘

来源:互联网 发布:淘宝小二电话人工 编辑:程序博客网 时间:2024/05/01 23:06
[编程题] 回文序列
如果一个数字序列逆置之后跟原序列是一样的就称这样的数字序列为回文序列。例如:
{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),以空格分隔。


输出描述:
输出一个数,表示最少需要的转换次数

输入例子:
41 1 1 3

输出例子:

2

解题思路:第一直觉:动态规划,关键是寻找状态转移点

// 每一步可能遇到2种状态
// a. 第一个与最后一个相等,则对回文序列没有贡献 
// b. 第一个与最后一个不等。为了构造回文序列,使用最小的步数,则两端的数据相差越小越好 
// 如果最后一个数据比第一个大,则前两个合并
// 如果第一个数据比最后一个大,则后两个合并 

#include <vector>#include <cstdio>using namespace std;int main(){int n, ans = 0,pBegin, pEnd;int vec[50];scanf("%d",&n);pBegin = 0; pEnd = n-1;for(int i = 0; i < n; ++i){scanf("%d",&vec[i]);}while(pBegin <= pEnd){if(vec[pBegin] == vec[pEnd]){++pBegin,--pEnd;}else if(vec[pBegin] < vec[pEnd]){vec[pBegin+1] +=vec[pBegin];++pBegin;++ans;}else{vec[pEnd-1]+=vec[pEnd];--pEnd;++ans;}}printf("%d\n",ans);return 0;} 


0 0
原创粉丝点击