题目理解
题目的意思是把长度为n的序列划分为多段,每一段都有一个权值。
其中权值表示为:
即{a1,a2,a3,an}的区间和。
然后呢还让我们每一个权值再乘p,p是一个长度为k的序列:
最后就是求 每一段的权值乘p 中值最大的那个,表示为:
思想
我们划分很多段:
dp[i][j]表示i在j段 加权值最大。
1. 如果不选取a[i]作为一个新的区间的起点,那么dp[i][j]就等于前i-1个数中选取j个区间时的最大加权和值,即dp[i][j]=dp[i-1][j]。
1. 如果选取a[i]作为一个新的区间的起点,那么dp[i][j]就等于前i-1个数中选取j-1个区间时的最大加权和值,即dp[i][j]=dp[i-1][j-1],再加上a[i]*b[j]的值。
code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
const int N=2e6+10;
const int mo=1e9+7;
int n,m,sum,x,y,z,k,len,a[N],b[N],c[N],f[N],p[N],dp[100001][201];
void solve()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i]; //{a1,a2,a3,an}
}
for(int i=1;i<=m;i++)
{
cin>>b[i]; //{p1,p2,p3,pn}
}
for(int i=1;i<=m;i++)
{
dp[0][i]=-1e18; //除了dp[0][0]初始化为0,剩下的全部初始化为不可达
}
for(int i=1;i<=n;i++)
{
dp[i][0]=-1e18;
for(int j=1;j<=m;j++)
{
dp[i][j]=max(dp[i-1][j],dp[i-1][j-1])+a[i]*b[j];
}
}
cout<<dp[n][m];
}
signed main()
{
ios_base::sync_with_stdio(false), cin.tie(nullptr);
int t=1;
while(t--)
{
solve();
}
}