链接:https://ac.nowcoder.com/acm/problem/14701
来源:牛客网
题目描述
给定两个长度为n的整数列A和B,每次你可以从A数列的左端或右端取走一个数。假设第i次取走的数为ax,则第i次取走的数的价值vi=bi⋅ax,现在希望你求出∑vi的最大值。
输入描述:
第一行一个数T,表示有T组数据。 对于每组数据,第一行一个整数n, 接下来两行分别给出A数列与B数列。
输出描述:
每一组数据输出一行,最大的∑vi。
思路:
区间:
表示区间
的最优解
首先考虑2个数时候,3个数时候,4个数时候的递推式容易发现的是
当是三个数的时候
进而猜测4个数,然后推之发现:
然后根据转移方程判断循环的顺序,次序。
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define DOF 0x7f7f7f7f
#define endl '\n'
#define mem(a,b) memset(a,b,sizeof(a))
#define debug(case,x); cout<<case<<" : "<<x<<endl;
#define open freopen("ii.txt","r",stdin)
#define close freopen("oo.txt","w",stdout)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
typedef long long ll;
using namespace std;
const int maxn = 2e5 + 10;
int a[1010],b[1010];
int dp[1010][1010];
int main(){
int t;cin>>t;
while(t--){
mem(dp,0);
int n;cin>>n;
for(int i=1;i<=n;++i)cin>>a[i];
for(int i=1;i<=n;++i)cin>>b[i];
for(int i=1;i<=n;++i){
dp[i][i]=a[i]*b[n];
}
// dp[i][j]=max(dp[i+1][j]+a[i]*b[n-(j-i+1)],dp[i][j-1]+a[j]*b[n-(j-i+1)]);
for(int i=n;i>0;--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)]);
}
}
cout<<dp[1][n]<<endl;
}
}



京公网安备 11010502036488号