比较直接的dp,状态当前选择左端还是右端,以及i之前选了几个左端
dp[ i ][ j ][ 0/1 ], 表示当前选择右端,1表示当前选择左端,j表示到达i时,已经选择j个左端。
#include<bits/stdc++.h> using namespace std; const int maxn=1100; int a[maxn],b[maxn],dp[maxn][maxn][2];//到达第i个点,选了j个左端点 int main() { int n,t; cin>>t; while(t--) { cin>>n; memset(dp,0,sizeof(dp)); memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); 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++) { for(int j=0;j<=i;j++) { if(j>0) dp[i][j][1]=max(dp[i][j][1],max(dp[i-1][j-1][0],dp[i-1][j-1][1])+a[j]*b[i]); dp[i][j][0]=max(dp[i][j][0],max(dp[i-1][j][0],dp[i-1][j][1])+a[n-i+j+1]*b[i]); } } int ans=0; for(int i=0;i<=n;i++) { ans=max(ans,max(dp[n][i][0],dp[n][i][1])); } cout<<ans<<endl; } }