题意:N位小朋友站成一行,每个小朋友有一个分值。
你给这N位小朋友发糖果,必须满足以下要求:
1、每个小朋友至少有一个糖果2、分值高的比邻居分值低的糖果数多。求最少糖果数。
我的思路:把这一列小朋友分成多个邻居分值不一样的段。比如(1,2,3,3)分成(1,2,3)和(3)两段。然后再找出每个段单调的终点,如果是单调上升就从第一个点一次往后增1,如果是单调下降就从最后一个点往前增1,先上升再下降的极小值则是两端较大的值。
其实这个思路跟网上简单思路的本质是一样的:从左往右扫,后面如果比前面的分值大,则后面的值是前面的加1,否则为1.然后从后往前扫,使得所有的点满足第二条。不过这题是我自己做出来的,还是蛮开心的。
代码如下(非常长):
int getCandy(vector<int> filtered)
{
vector<int> ans,trend;
int i=0,j,k,res=0,num=0,end,size;
if(size==1) return 1;
size=filtered.size();
for(i=0;i<size;i++) ans.push_back(1);
i=1;
while(i<size)
{
num=0;
while(filtered[i]>filtered[i-1]&&i<size)
{
num++;
i++;
}
if(num>0)trend.push_back(num*1);
num=0;
while(filtered[i]<filtered[i-1]&&i<size)
{
num++;
i++;
}
if(num>0)trend.push_back(num*-1);
}
i=0;
j=0;
while(i<size&&j<trend.size())
{
if(trend[j]>0)
{
ans[i]=1;
k=i+trend[j];
i++;
for(; i<=k; i++) ans[i]=max(ans[i],ans[i-1]+1);
if(i==size-1) break;
i--;
}
else if(trend[j]<0)
{
k=i-trend[j];
ans[k]=1;
k--;
for(k; k>=i; k--)ans[k]=max(ans[k],ans[k+1]+1);
i=i-trend[j];
}
j++;
}
j=0;
while(j<ans.size())
{
res=res+ans[j];
j++;
}
return res;
}
int candy(vector<int>& ratings)
{
int i=0,j,k,res=0;
vector<int> filter;
while(i<ratings.size())
{
filter.push_back(ratings[i]);
if(i==ratings.size()-1||ratings[i]==ratings[i+1])
{
res+=getCandy(filter);
filter.clear();
}
i++;
}
return res;
}