2017年浙江工业大学大学生程序设计迎新赛决赛—网络同步赛 G-取数游戏(区间dp)

来源:互联网 发布:客管家软件好用吗 编辑:程序博客网 时间:2024/05/16 19:08
给定两个长度为n的整数列A和B,每次你可以从A数列的左端或右端取走一个数。假设第i次取走的数为ax,则第i次取走的数的价值vi=bi⋅ax,现在希望你求出∑vi的最大值。

输入描述:

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

输出描述:

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

输入

221 10002 151 3 5 2 41 2 3 4 5

输出

200152

说明

对于第二个样例,第一次从左边取走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,每次从第n次取的情况开始,因为每个数都可能第n次取


#include<bits/stdc++.h>using namespace std;const int N=1005;int dp[N][N],a[N],b[N];int main(){    int t,i,j,n;    cin>>t;    while(t--)    {        memset(dp,0,sizeof(dp));        cin>>n;        for(i=1; i<=n; i++)            cin>>a[i];        for(i=1; i<=n; i++)            cin>>b[i];        for(i=n;i>=1;i--)        {            for(j=i;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)]);            }        }        cout<<dp[1][n]<<endl;    }    return 0;}

阅读全文
0 0
原创粉丝点击