EOJ # 3686 palindrome string

A single point of time: 2.0 sec
Memory Limit: 512 MB
will not be judged before the QQ small square palindromic sequence, and now he would, so he was eager to teach you.
It refers to a palindrome a number of columns being read and the counter reading are the same number of columns, such as "12321" and "1221."
Just tell you to listen is definitely not enough, in order to express themselves, QQ small parties now want to test you.
Now QQ small square will give you the number of columns consisting of n numbers a1, a2, ⋯, an. He wherein each operation allows you to combine two adjacent numbers ai and ai + 1 (i <n) , the two numbers after merging remain in their original position (after two leaving only a few number of bins), but it becomes ai + ai + 1. QQ small side wondering requires a minimum of several such operations, this series will become a palindrome columns.
Input format
input contains two lines, the first line of an integer n (1≤n≤10 ^ 6), it represents the length of the sequence.
The second line contains n space-separated numbers a1, a2, ⋯, an ( 0≤ai≤10 ^ 9), the number of columns.
Output format
output contains an integer indicating the minimum number of operations
sample
INPUT1
. 3
. 1 2. 3
OUTPUT1
. 1
INPUT2
. 3
. 1 2. 4
Output2
2
Input3
. 3
. 3. 3. 3
OUTPUT3
0
tips
For a sample: only one step, that is, before the two merged.
For the sample two: only when combined into a number of before they meet the requirements listed palindrome, it requires two steps.
For the sample three: itself is a palindromic sequence, you do not need to merge.

This problem looks very ignorant I first force, the first reaction zone DP, but n <= 10 ^ 6, clearly not in accordance with the complexity of the range of DP, but also that this problem should be O (n) or O (nlogn), the former possibility more

We come back to look at the subject:
every operation which allows you to combine adjacent two numbers a [i] and a [i + 1] (i <n), the two numbers after merging remain in their original positions (two numbers after leaving only a combined number), but becomes a [i] + a [i + 1]

This is very interesting, because no matter how we merge, the relative position is always the same
popular terms: that is, as long as I had in front of you, as long as I did and you merge, then after the merger is still in front of you I'm sure
that if I can think: as long as a number of the combined pre-merger by a [1] ([n] a) obtained, then the combined after a certain number of sequences leftmost (rightmost)
as a palindromic sequence , about equal to the number of ends is the minimum, but after just about equal to the number of ends, and then go to the middle of the rest of the sequence of left and right ends are equal ?????? (a little like recursion)
then this is interesting , we set the two pointers and l r, l and r start means 1 and n, since we must first ensure that the combined number of left and right ends are equal, then we take a look at points r and l numbers are not equal, and if so, l and r of each fill condensing step.
If not equal, then that will be a merger of small and under, and move a pointer, and then determine whether the same, and the answer +1
say may be a bit abstract, the specific code is like this:

while(le<ri)
 {
  if(an[le]==an[ri])le++,ri--;
  else if(an[le]<an[ri])an[le+1]+=an[le],le++,ans++;
  else an[ri-1]+=an[ri],ri--,ans++;
 }

Considering that the number of columns may be palindromic odd term may be even-numbered, so that restriction le <ri
final output on the line ans

Should not the complete code, right ?????? core code that piece just now

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define rt long long
using namespace std;
inline rt read()
{
 register rt u=0,v=0;register char ch=getchar();
 while(!isdigit(ch)){if(ch=='-')v=1;ch=getchar();}
 while(isdigit(ch)){u=u*10+ch-'0';ch=getchar();}
 return v ? -u : u;
}
rt n,le,ri,ans,an[1000010];
int main()
{
 n=read();
 le=1,ri=n;
 for(int i=1;i<=n;i++)
  an[i]=read();
 while(le<ri)
 {
  if(an[le]==an[ri])le++,ri--;
  else if(an[le]<an[ri])an[le+1]+=an[le],le++,ans++;
  else an[ri-1]+=an[ri],ri--,ans++;
 }
 printf("%lld",ans);
 return 0;
}
Released five original articles · won praise 0 · Views 106

Guess you like

Origin blog.csdn.net/wckdzz/article/details/104720008