JAVAMAN is visiting Dream City and he sees a yard of gold coin trees. There are n trees in the yard. Let’s call them tree 1, tree 2 …and tree n. At the first day, each tree i has ai coins on it (i=1, 2, 3…n). Surprisingly, each tree i can grow bi new coins each day if it is not cut down. From the first day, JAVAMAN can choose to cut down one tree each day to get all the coins on it. Since he can stay in the Dream City for at most m days, he can cut down at most m trees in all and if he decides not to cut one day, he cannot cut any trees later. (In other words, he can only cut down trees for consecutive m or less days from the first day!)
Given n, m, ai and bi (i=1, 2, 3…n), calculate the maximum number of gold coins JAVAMAN can get.
Input
There are multiple test cases. The first line of input contains an integer T (T <= 200) indicates the number of test cases. Then T test cases follow.
Each test case contains 3 lines: The first line of each test case contains 2 positive integers n and m (0 < m <= n <= 250) separated by a space. The second line of each test case contains n positive integers separated by a space, indicating ai. (0 < ai <= 100, i=1, 2, 3…n) The third line of each test case also contains n positive integers separated by a space, indicating bi. (0 < bi <= 100, i=1, 2, 3…n)
Output
For each test case, output the result in a single line.
Sample Input
2
2 1
10 10
1 1
2 2
8 10
2 3
Sample Output
10
21
Hint
s:
Test case 1: JAVAMAN just cut tree 1 to get 10 gold coins at the first day.
Test case 2: JAVAMAN cut tree 1 at the first day and tree 2 at the second day to get 8 + 10 + 3 = 21 gold coins in all.
题目链接
- 题意:一共给定n棵树,每棵树都有自己初始价值和增长价值,一共有m天可以砍树,必须要连续砍,如果一旦停下就不能再砍了。问获得最大价值。
- 思路:贪心,dp。这道题目有点背包的意思,但是又因为它的价值是一直在变的,所以又不能单纯的dp。要先对增量进行排序,即贪心,然后再背包。每一棵树每天只有两个状态,砍或者不砍。
定义dp[i][j]数组为第j天砍第i棵树获得的最大价值
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1] + trees[i].init + trees[i].add * (j - 1));
第i棵树:
1、第j天没砍:dp[i - 1][j]
2、第j天砍了(说明之前没砍dp[i -1][j - 1],树到第j天积累的价值: trees[i].init + trees[i].add * (j - 1))),
dp[i - 1][j -1] + trees[i].init + trees[i].add * (j - 1));
这两种状态找一个最大的即可。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int dp[255][255];
struct tree
{
int init, add;
bool operator < (const tree & obj) const
{
return add < obj.add;
}
}trees[260];
int main()
{
int TestCase;
cin >> TestCase;
while(TestCase--)
{
int n, m;
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) scanf("%d", &trees[i].init);
for(int i = 1; i <= n; i++) scanf("%d", &trees[i].add);
sort(trees + 1, trees + 1 + n);
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1] + trees[i].init + trees[i].add * (j - 1));
}
printf("%d\n", dp[n][m]);
memset(dp, 0, sizeof(dp));
}
return 0;
}
本文探讨了一种基于贪心和动态规划的金币树砍伐策略,旨在帮助JAVAMAN在有限时间内,通过连续砍伐特定数量的树来获取最大数量的金币。策略涉及对树的增长价值进行排序,并使用DP算法确定最佳砍伐方案。
&spm=1001.2101.3001.5002&articleId=88344819&d=1&t=3&u=0a3ba23d3284441fbf3930b63851fae6)
542

被折叠的 条评论
为什么被折叠?



