高效算法设计的介绍
你如果你使用暴力的话有一些题目因为时间复杂而度过高导致只能拿到部分分,所以今天让我们通过举例题目的方式让大家理解高效算法设计.
前缀和差分动态规划都是高效算法设计的方法.
实践
饥饿的狼
有一头🐺叫Wolf
有一群🐏每只🐏都叫Sheep
现在在位置1~n之间,第i个位置上都有ai 只 Sheep
Wolf处于饥饿状态以致于它最多能走k步,它每一步可以选择往左走或者往右走
但它不会走到1~n以外的位置,当它位于第i个位置上的时候就可以吃掉这个位置上所有的Sheep.某个位置上的Sheep被吃掉后,Sheep的数量就会变为0,但仍然可以走到该位置。
为了帮助Wolf吃到更多的🐏,你可以帮助他从任意位置出发,注意当它一开始出现在某个位置时需要花费一步
输入描述
第一行两个整数 n,k
分别表示坐标右边界和Wolf最多走的步数
第二行n个整数代表第i个位置Sheep的数量
输入描述
第一行两个整数 n,k
分别表示坐标右边界和Wolf最多走的步数
第二行n个整数代表第i个位置Sheep的数量
样例1
输入
6 3
9 9 9 2 3 1
输出
27
提示
样例解释
对于样例1来说我们可以让狼这样走
-
第一步选择位置为1,并把 i=1位置的羊吃掉,此时吃了9只羊
-
第二步选择向右走, 并把 i=2位置的羊吃掉,此时吃了18只羊
-
第三步选择向右走, 并把 i=3位置的羊吃掉,此时吃了27只羊
数据范围
对于40%的数据: 1<=n<=1000
对于100%的数据有: 1<=n<=105,1<=ai<=105
题目解释
题意:找出长度为k和最大的序列(在数组a中)
暴力解:
时间复杂度过高,数据高的测试点通不过。
主代码:
int big_sum =0;
for (int i=0; i < n-k; i++){
int sum = 0;
for (int j = 0; j < k;j ++){
sum += num[i+j];
}
if (sum > big_sum){
big_sum = sum;
}
}
满分解✅:
初步涉及到动态规划
先计算从1~K的羊的个数的总和,然后增加这个序列的后面一个元素减去这个序列第一个元素形成了一个挪动的效果。
然后再打擂台算出和最大的一组
1~K的和:
我把a定义成了num
long long sum = 0;
for (int i =0; i < k; i++){
sum += num[i];
}
打擂台移动:
long long sum = 0;
for (int i =0; i < k; i++){
sum += num[i];
}
long long max_sum = sum;
for (int i =k; i < n; i++){
sum += num[i]-num[i-k];
max_sum = max(sum,max_sum);
}
总体代码
#include <bits/stdc++.h>
using namespace std;
int main(){
long long n,k;
cin >> n >> k;
long long num[n];
long long max_ = 0;
for (int i =0; i < n; i++){
cin >> num[i];
if (num[i] > max_){
max_ = num[i];
}
}
if (k >= n){
cout << max_;
return 0;
}
long long sum = 0;
for (int i =0; i < k; i++){
sum += num[i];
}
long long max_sum = sum;
for (int i =k; i < n; i++){
sum += num[i]-num[i-k];
max_sum = max(sum,max_sum);
}
cout << max_sum;
return 0;
}
总结一下
在饥饿的狼这道题,可以演变出很多道题,比如求数列的最大连续和,题目换了题意不变一定要细心观察.