zoukankan      html  css  js  c++  java
  • 牛客网2017年浙江工业大学大学生程序设计迎新赛决赛 取数游戏2

    题目描述

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

    输入描述:

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

    输出描述:

    每一组数据输出一行,最大的∑v
    i
    示例1

    输入

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

    输出

    2001
    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

    备注:

    T≤10
    1≤n≤103
    1≤ai,bi≤103
     
    区间DP的典型题,
     状态转移方程:dp[i][j]=max(dp[i+1][j]+a[i]*b[n-(j-i)],dp[i][j-1]+a[j]*b[n-(j-i)]);(dp[i][j]为区间[i,j]的最大值)
    代码如下:
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <map>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <cmath>
    using namespace std;
    typedef long long ll;
    #define INF 0x3f3f3f3f
    int n;
    int a[1100];
    int b[1100];
    int dp[1100][1100];
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
         int n;
         scanf("%d",&n);
         memset(dp,0,sizeof(dp));
         for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
         for(int i=1;i<=n;i++)
            scanf("%d",&b[i]);
          for(int i=1;i<=n;i++)
            dp[i][i]=b[n]*a[i];
          for(int i=n-1;i>=1;i--)
            for(int j=i+1;j<=n;j++)
           dp[i][j]=max(dp[i+1][j]+a[i]*b[n-(j-i)],dp[i][j-1]+a[j]*b[n-(j-i)]);
          printf("%d
    ",dp[1][n]);
        }
        return 0;
    }
  • 相关阅读:
    C#高级编程第11版
    C#特性
    设计模式 单一职责原则
    设计模式 依赖倒置原则
    C# 预处理指令
    毕业设计 python opencv实现车牌识别 矩形矫正
    毕业设计 python opencv实现车牌识别 颜色判断
    毕业设计 python opencv实现车牌识别 界面
    南昌大学航天杯第二届程序设计竞赛校赛网络同步赛 I
    南昌大学航天杯第二届程序设计竞赛校赛网络同步赛 G
  • 原文地址:https://www.cnblogs.com/a249189046/p/8109298.html
Copyright © 2011-2022 走看看