[Introduction to Niuke Algorithm Competition Section 6 Exercises] Getting started with the number game 2 dp

Topic link: Access Game 2

Title

Given two integer sequences A and B of length n, you can take a number from the left or right end of the A sequence each time. Assuming that the number taken for the i-th time is ax {a_x}ax, Then the value of the number taken for the i-th time vi = bi ⋅ ax {v_i=b_i⋅a_x}vi=biax, Now I hope you find ∑ vi {∑v_i}viThe maximum value.

answer

Analyzing this question, it is easy to find that the optimal solution of each step cannot be the overall optimal solution, so it is necessary to solve this problem by requiring an elegant "violence".
Since this question can only take numbers from the leftmost and rightmost ends at a time, we can enumerate how many numbers are taken from the left and right ends to get the result.
Suppose dp[i][j]: the answer with i numbers on the left and j numbers on the right.
State transition equation:
dp [i] [j] = max (dp [i − 1] [j] + a [i] ∗ b [i + j], dp [i] [j − 1] + a [n − j + 1] ∗ b [i + j]) {dp[i][j]=max(dp[i-1][j]+a[i]*b[i+j],dp[i][ j-1]+a[n-j+1]*b[i+j])}dp[i][j]=max(dp[i1][j]+a[i]b[i+j],dp[i][j1]+a[nj+1]b[i+j])

Pay attention to the boundary conditions to prevent the array from crossing the boundary! ! !

Code

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
using namespace std;
//extern "C"{void *__dso_handle=0;}
typedef long long ll;
typedef long double ld;
//typedef int fuck;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
#define lowbit(x) x&-x
//#define int long long

const double PI=acos(-1.0);
const double eps=1e-6;
const ll mod=1e9+7;
const int inf=0x3f3f3f3f;
const int maxn=1e5+10;
const int maxm=100+10;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

int dp[1005][1005];
int a[1005],b[1005];

int main()
{
    
    
	int t;
	scanf("%d",&t);
	while(t--)
	{
    
    
		memset(dp, 0, sizeof(dp));
		memset(a, 0, sizeof(a));
		memset(b, 0, sizeof(b));
		int n; scanf("%d",&n);
		for(int i=1;i<=n;i++) scanf("%d",&a[i]);
		for(int i=1;i<=n;i++) scanf("%d",&b[i]);
		int ans=0;
		for(int i=0;i<=n;i++)
		{
    
    
			for(int j=0;j<=n;j++)
			{
    
    
				if(!i && !j) continue;
				if(i==0 && j) dp[i][j]=dp[i][j-1]+a[n-j+1]*b[i+j];
				else if(i && j==0) dp[i][j]=dp[i-1][j]+a[i]*b[i+j];
				else dp[i][j]=max(dp[i-1][j]+a[i]*b[i+j],dp[i][j-1]+a[n-j+1]*b[i+j]);
			}
			ans=max(dp[i][n-i],ans);
		}
		printf("%d\n",ans);
	}
}

Guess you like

Origin blog.csdn.net/weixin_44235989/article/details/108284279