• DP53 取数游戏


    题解:

    dp[L][R]:表示从左端取L个,从右端取R个

    状态转移: dp[L][R]=max(dp[L][R],max(dp[L-1][R]+a[L]*b[L+R],dp[L][R-1]+a[n-R+1]*b[L+R]));

    描述

    给定两个长度为 n 的整数列 A 和 B ,每次你可以从 A 数列的左端或右端取走一个数。假设第 i 次取走的数为 A_x \Ax​ ,则第i次取走的数的价值 v_i = b_i \times a_x \vi​=bi​×ax​  ,现在希望你求出 \sum_{i=1}^n v_i \∑i=1n​vi​ 的最大值。

    输入描述:

    第一行输入一个正整数 n ,表示数列 A 和 B 的长度。

    第二行和第三行各输入 n 个正整数,分别表示数列 A 和 B 的元素

    输出描述:

    按题目要求输出最大值

    示例1

    输入:

    2
    1 1000
    2 1

    复制输出:

    2001

    复制

    示例2

    输入:

    5
    1 3 5 2 4
    1 2 3 4 5

    复制输出:

    52

    复制说明:

    第一次从左边取走a1,v1=a1⋅b1=1,
    第二次从左边取走a2,v2=a2⋅b2=6,
    第三次从右边取走a5,v3=a5⋅b3=12,
    第四次从右边取走a4,v4=a4⋅b4=8,
    

    第五次取走剩下的a3,v5=a3⋅b5=25。

    总价值∑vi=1+6+12+8+25=52

    1. #include <iostream>
    2. using namespace std;
    3. int a[1005];
    4. int b[1005];
    5. int dp[1005][1005];
    6. //dp[i][j]表示从坐标去i个右边取j个
    7. int main() {
    8. int n;
    9. scanf("%d",&n);
    10. for(int i=1;i<=n;i++)
    11. {
    12. cin>>a[i];
    13. }
    14. for(int i=1;i<=n;i++)
    15. {
    16. cin>>b[i];
    17. }
    18. for(int L=0;L<=n;L++)
    19. {
    20. for(int R=0;R+L<=n;R++)
    21. {
    22. if(L>0&&R==0)
    23. {
    24. dp[L][R]=max(dp[L-1][R]+a[L]*b[L],dp[L][R]);
    25. }
    26. else if(L==0 &&R>0)
    27. {
    28. dp[L][R]=max(dp[L][R],dp[L][R-1]+a[n-R+1]*b[R]);
    29. }
    30. else if(L>0 &&R>0)
    31. {
    32. dp[L][R]=max(dp[L][R],max(dp[L-1][R]+a[L]*b[L+R],dp[L][R-1]+a[n-R+1]*b[L+R]));
    33. }
    34. }
    35. }
    36. int ans=0;
    37. for(int i=0;i<=n;i++)
    38. {
    39. ans=max(dp[i][n-i],ans);
    40. }
    41. cout<<ans<<"\n";
    42. return 0;
    43. }

  • 相关阅读:
    【USB声卡】magic_uac 开发板介绍
    Redis - 0、几款可视化工具
    多商家AI智能名片商城系统(开源版)——构建高效数字化商业新生态
    汇编基础知识
    直接插入排序,折半插入排序,冒泡排序,快速排序
    『Linux升级路』基础开发工具——vim篇
    Spring注解驱动之@Bean注解指定初始化和销毁的方法
    【无标题】
    前端学习基础知识
    【刷题笔记9.25】LeetCode:相交链表
  • 原文地址:https://blog.csdn.net/qq_42434171/article/details/126967927