Java实现 蓝桥杯 算法提高 进攻策略加强(暴力)

参考代码地址
博主的代码写的很好,只不过对于我这样的小白,看了半天才把代码看懂,我这里主要总结一下自己的思路以及贴出自己理解的注解。希望能帮助到和我一样的小白。

问题描述
  植物大战僵尸这款游戏中,还有一个特别的玩儿法:玩家操纵僵尸进攻植物。
  首先,僵尸有m种(每种僵尸都是无限多的),玩家可以选择合适的僵尸来进攻。使用第i种僵尸需要花费Wi资源,可以得到Pi的攻击效果。在这里,我们认为多个僵尸总的攻击效果就是他们每个攻击效果的代数和。
  地图共有n行,对于第i行,最左端有若干植物,这些植物需要至少Qi的攻击才能被全部消灭。若一行上的植物全部被消灭,我们称这一行被攻破。
  由于资源紧张,你只有总量为K的资源,不一定能够攻破所有行。但统治者希望攻破相邻的T行,并希望T尽量的大。你能帮他算出T的值吗?
输入格式
  第一行三个非负整数:m、n、K;
  第二行m个正整数,第i个数表示Wi;
  第三行m个正整数,第i个数表示Pi;
  第四行n个非负整数,第i个数表示Qi。
输出格式
  3 11 39
  5 2 11
  3 1 7
  5 3 6 10 3 2 4 200 1 1 1
样例输入
一个满足题目要求的输入范例。
例:
2 2
1 2
3 4
样例输出
4
数据规模和约定
  对于70%的数据:n<=1000

对于100%的数据:n<=200000,m<=100,K<=1000000,所有Pi、Qi<=100000000
这道题出的存在歧义,我们一般看到这道题都会理解为,每一行可以用不同的僵尸去攻击已到达花费资源最小这个条件。但是通过博主的代码我理解的是每一行只用一种僵尸取攻击。
代码如下:

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class 进攻策略加强 {
	public static void main(String[] args) {
		Scanner s = new Scanner(System.in);
		int m = s.nextInt();
		int n = s.nextInt();
		int k = s.nextInt();
		int[] wi = new int[m];
		int[] pi = new int[m];
		for (int i = 0; i < pi.length; i++) {
			wi[i] = s.nextInt();
		}
		for (int i = 0; i < pi.length; i++) {
			pi[i] = s.nextInt();
		}
		int[] qi = new int[n];
		for (int i = 0; i < qi.length; i++) {
			qi[i] = s.nextInt();
		}
		int T = 0;
		// 构造动态数组,数组的长度是i,变换区间为:[0,i]->[j,j+i],
		// 从而计算出当资源用完时,可以最大攻破的数组长度,即为最终答案。
		for (int i = n - 1; i >= 0; i--) {// i为数组长度
			for (int j = 0; j + i < n; j++) {// j决定从哪一行开始
				int a = k;
				int count = 0;
				for (int z = j; z <= j + i; z++) {// 遍历[j,j+i]的区间
					int x = getPrefferred(wi, pi, qi, z);
					if (a >= x) {
						count++;
						a -= x;
					} else {
						break;
					}
				}
				// 更新一下T的值,进行下一次循环
				if (count > T) {
					T = count;
					if (T >= i + 1) {
						System.out.println(T);
						return;
					}
				}
			}
		}
		System.out.println(T);
	}

	static Map<Integer, Integer> map = new HashMap<Integer, Integer>();

	// 记忆性递归
	public static int getPrefferred(int[] wi, int[] pi, int[] qi, int index) {
		Integer caches = map.get(qi[index]);
		if (caches != null)
			return caches;
		// 定义一个最大值,便于更新每一行的最小耗费
		int price = Integer.MAX_VALUE;
		for (int i = 0; i < wi.length; i++) {
			// 第index行最小花费的资源(每一行只能用一种僵尸)
			int pc = (int) (Math.ceil(qi[index] * 1.0 / pi[i]) * wi[i]);
			if (pc < price) {
				price = pc;
			}
		}
		map.put(qi[index], price);
		return price;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值