0奇怪的段【算法赛】 - 蓝桥云课 (lanqiao.cn)
基础dp:
#include<iostream>
#include<cstring>
#include<algorithm>using namespace std;const int N=1e5+6;typedef long long ll;ll f[N][206];
ll a[N];
ll sum[N];
ll p[206];
int n,k;int main(){cin>>n>>k;for(int i=1;i<=n;i++){scanf("%lld",&a[i]);sum[i]=sum[i-1]+a[i];}memset(f,-0x3f,sizeof f);f[0][0]=0;for(int i=1;i<=k;i++) scanf("%lld",&p[i]);for(int i=1;i<=n;i++){for(int j=1;j<=k;j++){for(int k=0;k<=i-1;k++){f[i][j]=max(f[i][j],f[k][j-1]+(sum[i]-sum[k])*p[j]);}}} cout<<f[n][k];return 0;
}
优化过程:
优化的后的dp:
#include<iostream>
#include<cstring>
#include<algorithm>using namespace std;const int N=1e5+6;typedef long long ll;ll f[N][206];
ll a[N];
ll sum[N];
ll p[206];
int n,k;int main(){cin>>n>>k;for(int i=1;i<=n;i++){scanf("%lld",&a[i]);sum[i]=sum[i-1]+a[i];}memset(f,-0x3f,sizeof f);f[0][0]=0;for(int i=1;i<=k;i++) scanf("%lld",&p[i]);for(int i=1;i<=n;i++){for(int j=1;j<=k;j++){f[i][j]=max(f[i-1][j]+p[j]*a[i],f[i-1][j-1]+a[i]*p[j]);}} cout<<f[n][k];return 0;
}