C. George and Job
题目连接
这是一道二维的dp。
题目的大致意思为给你n个数,每一段有m个数,取k段,并且每一段区间没有交叉。数据类型要用long long。
用sum数组记录前缀和,dp[i][]j]中i表示到第i个数时取了j段区间的最大和。
dp[i][j]可以由dp[i-1][j]没有添加区间得到,也可以由dp[i-m][j-1]添加了一段区间得到。所以得到的状态转移方程为dp[i][j]=max(dp[i-1][j],dp[i-m][j-1]+sum[i]-sum[i-m];
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll sum[5500],dp[5500][5500],a;
int main()
{
ll n,m,k,i,j;
scanf("%lld %lld %lld",&n,&m,&k);
memset(sum,0,sizeof(sum));
memset(dp,0,sizeof(dp));
for(i=1; i<=n; i++)
{
scanf("%lld",&a);
sum[i]=a+sum[i-1];
}
for(i=1; i<=n; i++)
for(j=1; j<=k; j++)
if(i-m>=0)
dp[i][j]=max(dp[i-1][j],dp[i-m][j-1]+sum[i]-sum[i-m]);
printf("%lld\n",dp[n][k]);
return 0;
}
这是自己第一次写博客,有不对的地方请多多指教。