题目:
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表
}
}
新人博主,以后会持续更新优质内容,关注绝对不亏