当前位置: 首页 > article >正文

取数游戏2(动态规划java)

取数游戏2

题目描述

给定两个长度为n的整数列A和B,每次你可以从A数列的左端或右端取走一个数。假设第i次取走的数为ax,则第i次取走的数的价值vi=bi⋅ax,现在希望你求出∑vi的最大值。

输入格式

第一行一个数T ,表示有T 组数据。对于每组数据,第一行一个整数 n ,接下来两行分别给出 A 数列与B 数列。

输出格式

每一组数据输出一行,最大的∑vi。

样例输入输出

样例输入

 
2
2
1 1000
2 1
5
1 3 5 2 4
1 2 3 4 5

样例输出

2001
52

数据范围

对于100的数据,保证 T≤10,1≤n≤1000,1≤ai,bi≤1000。

算法思路

首先题目中说的是每次取A数列的左端或右端,而B数列取的是第i个元素,暴力解的思路肯定就是通过回溯算法,把所有的情况尝试出来,但是这种思路肯定是会超时的,所以采用优化的算法动态规划。
首先定义dp数组的意义,因为最后要求的是A数列和B数列得出的∑vi最大值,所以可以定义为dp[0][n-1]为A数列[0 ~ n-1]得出的∑vi最大值,而dp[i][j]表示的是A数列[i ~ j]计算出来的∑vi最大值。
按照这个思路继续,继续推断递推公式,因为题干中说的是每次从A数列左端或右端取走一个数,并且乘上B数列的第i个元素,我们可以反向操作,初始的时候A数列没有元素,每次在左端或右端添加一个数,并且乘上B数列的第n-i个元素,通过这种逆向思路变可以推断出递推公式,既然每次是在左端或右端添加数,对于dp[i][j]的值来说,可能是由于dp[i+1][j]添加左端的数并且乘上B数列对应的元素得到的,也可能是dp[i][j-1]乘上B数列对应的元素得到的,取两者的最大值,那么就可以得出递推公式是dp[i][j]=max(dp[i+1][j]+B[n-j+i-1]*A[i],dp[i][j-1]+B[n-j+i-1]*A[j]),其中B[n-j+i-1]是左端或者右端添加数对应的B数列元素。
那么最后就是开始遍历dp数组来算出每个值了,其中dp数组的初始化有一个规律,就是最开始取的A数列的元素一定是乘上B数列中的最后的元素,因为dp[i]j的时候代表的意义一定是只有一个数的时候,所以在初始化dp数组的时候,让dp对角线元素等于A数列对应的元素乘上B数列最后一个元素作为初始值。
在这里插入图片描述
如上图,按照题干的测试案例给出的每个数组的值,其中dp数组是按照下面的元素和左面的元素来推断出来的,最后dp[0][4]便是答案。

代码

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        int T = scanner.nextInt();
        while (T>0){
            T-=1;
            //定义输入数据的初始化
            int n = scanner.nextInt();
            int []A = new int[n];
            int []B = new int[n];
            int [][]dp=new int[n][n];
            for(int i=0;i<n;++i){
                A[i]= scanner.nextInt();
            }
            for(int i=0;i<n;++i){
                B[i]= scanner.nextInt();
            }
            //让对角线上的元素等于B数组最后一个元素和A数组的第i个元素,动态规划的数组初始化
            for(int i=0;i<n;++i){
                dp[i][i]=A[i]*B[n-1];
            }
            for(int i=n-1;i>=0;i--){
                for(int j=i+1;j<n;++j){
                	//递推公式
                    dp[i][j]=Math.max(dp[i+1][j]+B[n-j+i-1]*A[i],dp[i][j-1]+B[n-j+i-1]*A[j]);
                }
            }
            System.out.println(dp[0][n-1]);
        }
    }
}

http://www.kler.cn/a/134254.html

相关文章:

  • 使用jmeter查询项目数据库信息,保存至本地txt或excel文件1108
  • Blender进阶:图像纹理节点和映射节点
  • 【VBA实战】用Excel制作排序算法动画续
  • 2024 年 8 个最佳 API 设计工具图文介绍
  • MTSET可溶于DMSO、DMF、THF等有机溶剂,并在水中有轻微的溶解性,91774-25-3
  • 重新认识HTTPS
  • MSSQL-逻辑级常用命令
  • 设计模式(二)-创建者模式(2-0)-简单工厂模式
  • CocoaPods podfile 文件配置
  • 丹麦能源袭击预示着更关键的基础设施成为目标
  • UOS统信操作系统QIcon::fromTheme详解
  • 翻译软件Mate Translate mac中文版介绍说明
  • NewStarCTF2023 Reverse Week3 EzDLL WP
  • nodejs+vue实验室上机管理系统的设计与实现-微信小程序-安卓-python-PHP-计算机毕业设计
  • c语言中*p1++和p1++有啥区别
  • 大数据Doris(二十五):Stream Load数据导入演示和其他导入案例
  • android适配鸿蒙系统开发
  • 说一说HTTP1.0、1.1、2.0版本区别和优化
  • c++中的String
  • 【算法】石子合并(区间dp)
  • Python学习之——正则表达式
  • 深度学习入门(第三天)——卷积神经网络
  • LangChain 4用向量数据库Faiss存储,读取YouTube的视频文本搜索Indexes for information retrieve
  • 系统移植-uboot
  • 012 C++ AVL_tree
  • 创邻科技亮相ISWC 2023,国际舞台见证知识图谱领域研究突破