赛码网--接金币(Java实现)(动态规划)

题目描述
									

 

小赛非常喜欢玩游戏,最近喜欢上了一个接金币的游戏。在游戏中,使用帽子左右移动接金币,金币接的越多越好,但是金币掉到地上就不能再接了。为了方便问题的描述,我们把电脑屏幕分成11格,帽子每次能左右移动一格。现在给电脑屏幕如图标上坐标:

 

也就是说在游戏里,金币都掉落在0-10这11个位置。开始时帽子刚开始在5这个位置,因此在第一秒,帽子只能接到4,5,6这三个位置中其中一个位置上的金币。问小赛在游戏中最多可能接到多少个金币?(假设帽子可以容纳无穷多个金币)。

输入

 

输入数据有多组。每组数据的第一行为以正整数n (0<n<100000),表示有n个金币掉在屏幕上上。在结下来的n行中,每行有两个整数x,T (0<T<100000),表示在第T秒有一个金币掉在x点上。同一秒钟在同一点上可能掉下多个金币。n=0时输入结束。输入数据以空格隔开

 

样例输入

 

7
6 3
8 2
9 3
7 1
6 2
5 1
7 2

 

输出

 

每一组输入数据对应一行输出。输出一个整数m,表示帽子最多可能接到m个金币。

 

样例输出

 

3

解题思路:看了一天的动态规划,终于解出了这道题,算是皇天不负有心人吧。

这个题目刚开始的时候真的是有点懵,取网上百度了一下题解,需要用到动态规划。于是开始了动态规划的学习历程。

下面就从动态规划的角度来讲解一下自己的思路:当下来金币的时候,小赛总会在他能够接近的三个(或者两个)位置,面临一个问题:接还是不接?接了的话,可能会在其他位置下来更多的,但是不在能够接近的范围内;但是不接的话,又会造成一定的损失(外一下一秒没有了怎么办)。从第一秒往最后一秒考虑的话,很难判断,因为你无法预判。但是如果我们从后往前考虑的话,就变得容易了。循环处理这11个位置,每次将下一秒三个位置(或两个位置)中较大值加到前一秒中。处理完后,dp[0][5]存储得就是我们想要得答案。

import java.util.Scanner;

public class Main {
    public static int get_max(int a,int b,int c){
        if(a>b)
            b = a;
        if (c>b)
            b = c;
        return b;
    }
    public static int dp_res(int[] a,int[] b,int max_second){
        int m = max_second+1;
        int n = 11;
        int[][] dp = new int[m][n];
        for(int i=0;i<a.length;i++)
            dp[b[i]][a[i]]++;//同一秒钟在同一点上可能掉下多个金币
        for(int i=m-2;i>=0;i--){
            for(int j=0;j<11;j++){
                //处理不同位置
                if(j == 0){
                    dp[i][j] += Math.max(dp[i+1][j],dp[i+1][j+1]);
                }else if(j==10){
                    dp[i][j] += Math.max(dp[i+1][j],dp[i+1][j-1]);
                }else{
                    dp[i][j] += get_max(dp[i+1][j-1],dp[i+1][j],dp[i+1][j+1]);
                }
            }
        }
        return dp[0][5];
    }
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] a = new int[n];
        int[] b = new int[n];
        int max_second = -999;
        for(int i=0;i<n;i++){
            a[i] = sc.nextInt();
            b[i] = sc.nextInt();
            if(max_second<b[i])
                max_second = b[i];
        }
        System.out.println(dp_res(a,b,max_second));
    }
}

这个问题跟数塔问题,还是很像的,感兴趣的可以看一下我的那篇博客。

加油~~~

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值