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;
}