Description
码头上有一批货物,它们被摆放成了n摞,每摞的个数(高度)为di,并排成一排。
现在包工头酋长想用一台特殊的搬运机, 用最少的次数,将这批货物全部取走。
这台搬运机的工作原理是:一次可以取走相邻几排最下面一层的所有货物。
例如:当货物共有4摞,每摞高度分别为2 3 1 2时,我们可以采用如下策略使得总使用次数最少
第一步:由于四摞货物是相邻的,取走这四摞货物最下面的一排货物,当前变为1 2 0 1
第二步:此时第三摞货物取空,第一、二摞和第四摞不相邻,取走前两摞货最下面一排,当前变为0 1 0 1第三步、第四步:分别取走第二摞和第四摞货物最下面一排,从而将这批货物全部取走
因此使用这台搬运机的最少次数为: 4
Input
输入数据包含两行
第一行包括一个整数n,含义如题面所述(1 <= n <= 100000)
第二行包括n个整数di,表示每摞货物的高度(个数) (0 <= di <= 10000)
Output
输出包含一个 整数,表示使用搬运机的最少次数
Sample Input 1:
4
2 3 1 2
Sample Output 1:
4
按照题目的思路写的代码:
#include<bits/stdc++.h>
using namespace std;
const int MAX = 1000005;
int n;
int a[MAX];
int main(void)
{
cin >> n;
for(int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
}
a[n + 1] = 0;
int flag = 0; // 如果为0,证明从1开始还没找到>0的数
int count = 0;
int zero = 0;
for(int i = 1; i <= n; i++)
{
if(a[i] == 0) zero++;
}
while(zero != n)
{
flag = 0;
for(int i = 1; i <= n + 1; i++)
{
// 还没找到首个大于0的数
if(a[i] == 0 && flag == 0)
{
flag = 0;
continue;
}
// 如果前面已经完成过减法,且当前为0,说明完成一次搬运
if(a[i] == 0 && flag == 1)
{
count++;
flag = 0;
break;
}
// 如果当前的数>0,就减
if(a[i] > 0)
{
a[i]--;
flag = 1;
if(i <= n && a[i] == 0) zero++; // 更新0的个数
}
}
}
cout << count << endl;
return 0;
}
上面代码的思路就是,每次从1开始,直到遇到首个非0的数。将这个数减1,并更新0的个数,标记为开始搬运了(flag=1)。如果当前的数是0,并且前一个数是搬运过了(flag==1),则搬运次数加一,并重新从1开始,直到0的个数等于n。
其他方法:
#include<bits/stdc++.h>
using namespace std;
const int MAX = 1000005;
int n;
int a[MAX];
int main(void)
{
cin >> n;
for(int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
}
int ans = 0;
for(int i = 1; i <= n; i++)
{
if(a[i] > a[i-1])
{
ans+= a[i]-a[i-1];
}
}
cout << ans << endl;
return 0;
}