求k个不覆盖的最大连续区间和,每个区间长度为m。
影响决策的因素有k和区间和,所以dp[i][j]的含义就显而易见了,表示在以第i个数的位置选择了j个子序列的最大值。
那么根据递推关系不难写出递推表达式dp[i][j] = max(dp[i-1][j],dp[i-m][j-1]+sum[i]);其中dp[i-1][j]的作用值得我们细细品味,它的作用是将状态转移过来。
而且因为区间的不覆盖性,我们要先枚举位置,再枚举子序列的个数。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<vector> #include<set> #include<map> #include<cmath> using namespace std; typedef long long ll; ll n,m,k,a[5005],dp[5005][5005],sum[5005]; int main(){ cin>>n>>m>>k; for(int i=1;i<=n;i++) cin>>a[i]; memset(dp,0,sizeof(dp)); memset(sum,0,sizeof(sum)); for(int i=m;i<=n;i++){ for(int j=i;j>=i-m+1;j--){ sum[i] += a[j]; } } for(int i=m;i<=n;i++){ for(int j=1;j<=k;j++){ dp[i][j] = max(dp[i-1][j],dp[i-m][j-1]+sum[i]); } } printf("%lld\n",dp[n][k]); return 0; }
时间: 2024-10-14 01:01:36