尺取
小初又来叨扰大家啦,也就是今天小初也才初步了解尺取这个简单的算法,小初还是紧赶慢赶的来写博客了,这是小初平生的第二次博客,本来俺也是本着完成任务的想法来写的,因为小初自己也知道自己学得也一点都不好,也怕被别人看笑话,所以,小初的博客也只会适合刚刚入门的新手的,那些大能们阔以纯当康个笑话,当然,小初也希望看小初博客的小哥哥小姐姐能够多多原谅小初的鲁莽和粗心,如果还阔以指出小初的不足之处就更好啦,另外,祝大家小年快乐呀!
那么,正题开始啦,首先,小初还是先双手奉上小初学校的题给有兴趣的观众老爷们康康。
小初与火锅更配
小初觉得这个题目呢是一个很基本的尺取啦,所谓尺取呢,顾名思义,大家阔以从名字上来初步认识一下这个算法呢,我们把尺取阔以分成尺子和拿取这俩部分,你康
尺子上是不是有很多的刻度捏,我们阔以取尺子上0至2或者0至6,还阔以取6至12等等任意一个尺子上有的区间都阔以取,该算法就是要我们把我们设的整个数组看成一把好长好长的尺子,然后找出我们最需要或是最优的一部分
首先让我们来康康题目告诉我们n的范围是20000000以下,所以我们需要用一把长为2000000的尺子,然后小初又特别的二,所以小初要了一把2222222的尺子,代码如下
#include<stdio.h>
int s[2222222];
随后,小初要给我们的尺子写上刻度,当然也就是题目中火锅的价值了
for(i=0;i<n;i++)
scanf("%lld",&s[i]);
小初的想法是先计算出最开始从第一盘到第m盘的火锅的价值,来做一个标准,代码如下
for(i=0;i<m;i++)
max+=s[i];
那么关键的地方到了,我们要标记两个尺子上的刻度来完成下面的代码,用一个i下标指向开头,用一个j下标指向i+m个刻度,用a来记录上次的价值之和,那么本次的a就是通过对上一次的a减去一开始j的刻度再加上后面新加入的j的刻度,而本次的a如果大于我们的标准,也就是max,就把a的值重新赋值给max,代码如下
for(i=0,j=m;i<n;i++,j++)
{
a=a-s[i]+s[j];
if(a>max)
max=a;
}
仔细看题,题目还说这个火锅呢是围成一圈的,很像小初写博客在绕圈圈,所以我们还要假如代码,完善后如下
for(i=0,j=m;i<n;i++,j++)
{
if(j==n)
j=0;
a=a-s[i]+s[j];
if(a>max)
max=a;
}
最后,小初要提醒大家在遇到错误的时候不要着急,写代码的时候一定要万般仔细啦,这道题一定要long long int的,因为我们的max很容易就超过了int的范围,这可是小初血一般的教训换来的呀
所以,完整代码如下
#include<stdio.h>
long long int s[2222222];
int main(void)
{
long long int i,j,m,n,max,a;
while(scanf("%lld%lld",&n,&m)!=EOF)
{
max=0;
for(i=0;i<n;i++)
scanf("%lld",&s[i]);
for(i=0;i<m;i++)
max+=s[i];
a=max;
for(i=0,j=m;i<n;i++,j++)
{
if(j==n)
j=0;
a=a-s[i]+s[j];
if(a>max)
max=a;
}
printf("%lld\n",max);
}
}
好啦,小初的博客写到这里,还只是讲了一个例题而已,大家是不是觉得小初特别啰里啰唆又在水博客,其实小初只是才疏学浅,自己对尺取的理解也是非常的片面,不知道从哪里入手,小初也是很可怜的呢。
上一篇: 饭桌上一片寂静