HDU-2182-Frog
这道题是一道dp哟~
题目大意:青蛙吃苍蝇问题,问在一条长度为n的路上,区间为[0, n),每一个点都有相对数量的苍蝇,这只青蛙在位置为0的地方,给定跳跃范围[A, B],青蛙在跳K步之后会疲惫,就无法再跳跃了,问青蛙最多能吃到多少只苍蝇。
本题思路:我们定义dp[i][j]
dp[i][j]表示第j次跳跃时,在i的位置,此时吃的最大苍蝇数。
那么我们的状态转移方程就从前面的状态的来或者维护当前的最大值。
d[i + j][k + 1] = max(dp[i + j][k + 1], dp[i][k] + a[i + j]);
表示第k + 1次的跳跃,在i + j的位置时,比较前面第k次的跳跃,在i的位置,跳跃j格,j在[A,. B]的范围之内,到达i + j位置的苍蝇数,与当前值比较,获得最大值即可。
初始化部分:dp[i][j]初始化为-1
dp[0][0] = a[0];是表示当前青蛙在位置为0的地方本来就有苍蝇。
我们在三重循环处理的时候记得判断一下i + j不能超过n的范围,并且还要判断在已经到达dp[i][k]的情况下才能进行dp[i + j][k + 1]的转移。其实这就是表示开始的位置已经固定了。不能自由选择开始的位置。
最后我们在跑一遍维护一下ans的最大值就可以拉~
代码部分:
#include <bits/stdc++.h>
#define mst(a, n) memset(a, n, sizeof(a))
using namespace std;
const int N = 1e2 + 10;
int t;
int n, a, b, k;
int q[N];
int dp[N][N];
int main()
{
cin >> t;
while (t--)
{
scanf ("%d%d%d%d", &n, &a, &b, &k);
for (int i = 0; i < n; i++)
{
scanf ("%d", &q[i]);
}
mst(dp, -1);
dp[0][0] = q[0];
for (int i = 0; i < n; i++)
{
for (int j = a; j <= b; j++)
{
for (int z = 0; z <= k; z++)
{
if (i + j < n && dp[i][z] != -1)
{
dp[i + j][z + 1] = max(dp[i + j][z + 1] , dp[i][z] + q[i + j]);
}
}
}
}
int ans = q[0];
for (int i = 0; i < n; i++)
{
for (int j = 0; j <= k; j++)
{
ans = max(ans, dp[i][j]);
}
}
cout << ans << endl;
}
return 0;
}