24字节面试真题 分糖 (提供递归和dp两种方法)~


题目:

     beiheng特别爱吃糖果。他奶奶家楼下正好有一个糖果专卖店,每天供应不同种类的糖果。beiheng预先拿到了糖果专卖店接下来n天的进货计划表

并针对每天的糖果种类标注好了对beiheng而言的美味值。beiheng当然想每天都能去买糖果吃,不过由于零花钱限制(beiheng零花钱并不多! )

以及健康考虑,beiheng决定原则上如果今天吃了,那么明天就不能吃。但beiheng认为凡事都有例外,所以她给了自己k次机会,

在昨天已经吃了糖果的情况下,今天仍然连续吃糖果!简单来说,beiheng每天只能吃一次糖果, 原则上如果昨天吃了糖果那么今天就不能吃,

但有最多k次机会打破这原则。beiheng不想浪费每次吃糖果的机会, 所以请你帮帮她规划一下她的吃糖果计划, 使得她能吃到的糖果美味值最大。

题目:

糖果美味值数组:1234567,k=1

输出:

19
解释:
最优的方案是选择选择第2、4、6天吃糖果,并在第7天打破次原则也吃糖果 (因为第6天已经吃过,原则上不能继续吃, 需要使用一次打破原则的机会)

递归方法

简单说一下思路,我们要写一个递归函数,返回当前index状态的最大美味值

k是记录当前还有特权的次数

一共有3中情况(其实还有一种就是今天不吃糖,但是使用特权,浪费次数么这不是,这种明显不是最优,直接忽略)

1.今天不吃

2.今天吃,明天不吃

3.今天吃,明天还吃 k-1

求三种情况的最大值返回

package 背包;

import java.util.Scanner;

public class 真题_分糖 {
	/*题目概述
	 * 小b今天吃了糖,明天就不能吃了,但有k次特例 求美味值最大
	 * 1 2 3 4 5 6 7 k=1
	 */
//从arr【index...最后】你有k次使用特权的能力,返回最大美味值,前面我不管
	//关于数组下标为啥要+1,提一嘴,因为结束的时候是到了n 不然数组越界
	//就是为了装最后一行
	//法一 暴力递归;
	static int a[]=new int [10];
	static int n;
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		 n=sc.nextInt();
		int k=sc.nextInt();
		for(int i=0;i<n;i++)
		{
			a[i]=sc.nextInt();
		}
		int ans=dp(a,0,k);
		System.out.println(ans);
		
	}
	static int dp(int a[],int index,int k)
	{
		if(index>=n) return 0;
		int p1=dp(a,index+1,k);//今天不吃糖  
		int p2=a[index]+dp(a,index+2,k);//今天吃糖,不用特权,则明天不能吃糖
		int p3=0;
		if(k>0)
		 p3=a[index]+dp(a,index+1,k-1);//今天吃糖+用特权 k-1
		
		return Math.max(Math.max(p1, p2), p3);
		
	}
	
}

该方法虽然好想,但数据大了肯定超时

所以法二进行了dp优化

package 背包;

import java.util.Scanner;

public class dp做法 {

	static int a[]=new int [10];
	static int n;
	static int [][]dp;
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		 n=sc.nextInt();
		int k=sc.nextInt();
		for(int i=0;i<n;i++)
		{
			a[i]=sc.nextInt();
		}
		dp=new int [n+2][k+1];
		int N=dp.length;
		int M=dp[0].length;
		//因为java数组自动初始化为0 ,所以不用单独填了
		for(int index=N-3;index>=0;index--)
		{//最后两行都是0,所以从倒数第三行开始填
			for(int times=0;times<M;times++)
			{
				int p1=dp[index+1][times];//今天不吃糖  
				int p2=a[index]+dp[index+2][times];//今天吃糖,不用特权,则明天不能吃糖
				int p3=0;
				if(times>0)
				 p3=a[index]+dp[index+1][times-1];//今天吃糖+用特权 k-1
				
				dp[index][times]= Math.max(Math.max(p1, p2), p3);
			}
		}
	
		System.out.println(dp[0][k]);
	/*	for(int i=0;i<N;i++)
		{
			for(int j=0;j<M;j++)
			{
				System.out.print(dp[i][j]+" ");
			}
			System.out.println();
		}*///查看dp表
		
	}
	
	
}


新人博主,以后会持续更新优质内容,关注绝对不亏

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值