VC1-牛牛吃草

文章描述了一个关于牛牛吃草的问题,其中涉及到动态规划和状态转移方程的运用。牛牛在每块草地上可以吃掉所有草,并按特定步长向右移动。目标是找到牛牛最多能吃多少斤草。通过建立状态转移方程f[i+1]=max(f[i],f[j]+w[i]),并遍历所有可能的起始位置和步长,可以求得最大吃草量。代码示例展示了如何实现这一算法。
摘要由CSDN通过智能技术生成

题目

现在有一排n块草地,第i块草地上有wi​斤草,以及一个数字ai​。当牛牛在第i块草地上时,他可以吃掉这个草地上所有的草,并且向右走到另一块草地。但是牛牛有强迫症,他向右走的距离必须是ai​的整数倍。例如:当牛牛在第3块草地,并且a3​=2时,他下一步就只能前往第5,7,9,…,块草地。

牛牛可以从任意一块草地开始不断的吃草并移动到下一个草地,并且可以在任意一块草地结束它的吃草之旅。
现在请问,牛牛在一次吃草之旅中,最多可以吃掉多少斤草?

输入描述:

  • 第一行一个整数n(1≤n≤103)。
  • 接下来一行n个整数表示wi​(1≤wi​≤100)。
  • 最后一行n个整数表示ai​(1≤ai​≤10)。

输出描述:一个整数,表示答案。

示例1

输入:

5
3 5 20 7 5
1 2 5 1 3

输出:23

说明:从第1块草地走到第3块,总草数为3+20=23。

示例2

输入:

3
10 11 5
2 1 1

输出:16


思路

题目明显是dp的题目,可以想到写状态转移方程,用f[i]表示到达第i块草地牛牛所能吃草的最大值。

到达第(i+1)块草地牛牛能吃草的值  = 前面任意一块能到达(i+1)块草地的吃草值 + 第(i+1)块草地的吃草值

状态转移方程:f[i+1] = Math.max(f[i], f[j] + w[i]);


代码

import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        //输入
        Scanner in = new Scanner(System.in);
        //Java中的Integer.parseInt()是将包装数据类型Integer转换为基本数据类型int
        int n = Integer.parseInt(in.nextLine()); //表示有一排n块草地
        String[] wStr = in.nextLine().split(" "); //存n块草地每块的草的斤数wi,n个wi
        String[] aStr = in.nextLine().split(" "); //存n块草地每块上的数字ai,n个ai

        int[] w = new int[n]; //存n块草地每块的草的斤数wi
        int[] a = new int[n]; //存n块草地每块上的数字ai
        int[] f = new int[n]; //存n块草地牛牛到每块草地时累计吃的草的斤数

        //i标记在哪一块草地上,j标记草地上数字的下标,i - j代表向右走的距离
        int i = 0, j = 0;

        //遍历n块草地
        for (i = 0; i < n; i++) {
            w[i] = Integer.parseInt(wStr[i]); //第i块草地的草斤数
            a[i] = Integer.parseInt(aStr[i]); //第i块草地上的数字
            f[i] = w[i];
        }

        //此处看不懂可以对照示例1、2代入理解
        for (i = 0; i < n; i++) {
            for (j = 0; j < i; j++) {
                if ((i - j) % a[j] == 0) {
                    f[i] = Math.max(f[i], f[j] + w[i]); //牛牛到第i块草地时能吃的草的最大斤数
                }
            }
        }

        //找出n块草地中牛牛吃的草的斤数的最大值
        int res = 0;
        for (i = 0; i < n; i++) {
            if (f[i] > res) {
                res = f[i];
            }
        }
        System.out.println(res);
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值