高效的算法设计

本文介绍了如何通过高效算法设计,如前缀和和差分动态规划,解决饥饿的狼问题,即求解最大连续羊群数量。暴力解法效率低,而动态规划提供了更优解。通过实例演示了如何计算1~K的羊群总和并进行移动操作来找到最大序列和。
摘要由CSDN通过智能技术生成

高效算法设计的介绍

 你如果你使用暴力的话有一些题目因为时间复杂而度过高导致只能拿到部分分,所以今天让我们通过举例题目的方式让大家理解高效算法设计.

前缀和差分动态规划都是高效算法设计的方法.

实践

饥饿的狼

有一头🐺叫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. 第一步选择位置为1,并把 i=1位置的羊吃掉,此时吃了9只羊

  2. 第二步选择向右走, 并把 i=2位置的羊吃掉,此时吃了18只羊

  3. 第三步选择向右走, 并把 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;
}

总结一下

在饥饿的狼这道题,可以演变出很多道题,比如求数列的最大连续和,题目换了题意不变一定要细心观察.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值