概述
就是k组数,每组是连续的m个数,求这些数最大和。群里有人推荐这道题,于是来写了一下,题目意思还是很好理解的,很简单的动规思路。 连续m个数,那就对每一个位置都算出前m个数的和,然后就是取k次的一个背包。
dp[i][j]=max(dp[i][j-1],dp[i-1][j-m]+d[j]);
i代表取的次数,j代表到第j个数。但是初始化还有一点细节要处理。
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int a[5005];
long long dp[5005], dp1[5005][5005];
long long max(long long a, long long b)
{
return a > b ? a : b;
}
int main()
{
int i, j, m, n, ans, k;
long long sum = 0, pre;
cin >> n >> m >> k;
for (i = 1; i <= n; i++)
cin >> a[i];
for (i = 0; i < m; i++)
{
dp[i] = 0;
sum = sum + a[i];
}
a[0] = 0; j = 0;
for (i = m; i <= n; i++)
{
sum = sum - a[j];
sum = sum + a[i];
dp[i] = sum;
j++;
}
for (i = 0; i < m; i++)
dp1[1][i] = 0;
for (i = m; i <= n; i++)
dp1[1][i] = max(dp1[1][i - 1], dp[i]);
for (i = 2; i <= k; i++)
{
for (j = i * m; j <= n; j++)
{
dp1[i][j] = max(dp1[i][j - 1], dp1[i-1][j - m] + dp[j]);
}
}
//for (i = 1; i <= n; i++)
// cout << dp[i] << " ";
//cout << endl;
//for (i = 1; i <= k; i++)
//{
// for (j = 1; j <= n; j++)
// cout << dp1[i][j] << " ";
// cout << endl;
//}
cout << dp1[k][n] << endl;
return 0;
}
好久不写动规,这次感觉不错,得写专题了,模拟已经够了。
最后
以上就是外向芹菜为你收集整理的George and Job的全部内容,希望文章能够帮你解决George and Job所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复