hdu3916Sequence Decomposition贪心

hdu3916Sequence Decomposition贪心
解:
(引)
比如一个序列2 3 4 3 3 1
如何拆成门函数分量使得长度尽量平均呢? 直观的想法是在消的过程中使序列尽量平均。
首先想到是左边第一个肯定要拆成2个门函数且应使其尽可能长,但也不是越长越好。

如果a[i] <= a[i+1] 那么消掉a[i]的时候,a[i+1]消掉肯定没坏处,因为如果不消,
不仅可能使答案变小,而且序列也会变的更加不平均
如果a[i] > a[i+1] 则本着使序列越来越平均的思想,消掉a[i]的时候自然是不要消掉a[i+1]了。

上述样例采用该贪心方法的过程是
2 3 4 3 3 1 消(1,3)
1 2 3 3 3 1 消(1,5)
0 1 2 2 2 1 消(2,5)
0 0 1 1 1 1 消(3,6)
0 0 0 0 0 0
故答案是3

至于O(n)算法 我方法可能比较抽象 借助左右2个指针i,j  不是每次都对每个数进行减法运算
而是借助  通过lazy操作来不断更新

View Code
#include<iostream>
#include
<algorithm>
using namespace std;
const int maxn=10005;
const int INF=1000000000;
int d[maxn];
int main()
{
int cas,n;
cin
>>cas;
while(cas--)
{
cin
>>n;
memset(d,
0,sizeof(d));
for(int i=1;i<=n;i++)scanf("%d",&d[i]);
int l=1,r=1,lazy=0,ans=INF;
for(int i=1;i<=n;i++)
{
if(d[r]<=d[r+1])r++;
else break;
}
while(l<=r)
{
ans
=min(ans,r-l+1);
while(d[l]-lazy==0)l++;
if(d[r]-lazy<=d[r+1])//当需要加入一个新的数时再减掉lazy
{
for(int i=l;i<=r;i++)d[i]-=lazy;
while(l<=r)
{
if(!d[l])l++;
else break;
}
lazy
=0;
while(d[r]<=d[r+1])r++;
}
lazy
++;
}
cout
<<ans<<endl;
}
}
原文地址:https://www.cnblogs.com/sook/p/2159040.html