zoj3211(贪心+dp)

来源:互联网 发布:饥饿游戏知乎 编辑:程序博客网 时间:2024/06/11 21:02

Dream City

Time Limit: 1 Second      Memory Limit: 32768 KB

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 ihas 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 nmai 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

22 110 101 12 28 102 3

Sample Output

1021

Hints:
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.


题意:一个人在一个城市待m天,这个城市一共有n棵树,一开始都有基值ai,如果不砍每天都会增大bi,人在这m天内必须连续每天砍一棵树,否则如果一天不砍就不能再砍,求能获得的最大值。(n>=m)

思路:一开始一直想不通为什么贪心+dp是正确的,后来想明白了。因为n>=m,所以要在m天内获得最大值,必须要每天都砍树,所以必定是从n棵树中选m棵树来砍。既然已经选定了m棵树接下来就是排序的问题了(谁先砍?),必然是斜率bi小的先砍。所以要贪心地把斜率小的放在前面。所以不管选哪m棵树,必然是斜率小的先砍,这就是要贪心的原因,再dp一下就okay了。

#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int n,m;int dp[255][255];struct node{int a,b;}tree[255];bool cmp(node x,node y){return x.b<y.b;}int main(){int t;cin>>t;while(t--){cin>>n>>m;for(int i=1;i<=n;i++)cin>>tree[i].a;for(int i=1;i<=n;i++)cin>>tree[i].b;//先贪心,斜率小的先砍sort(tree+1,tree+n+1,cmp);memset(dp,0,sizeof(dp));for(int i=1;i<=n;i++){for(int j=1;j<=min(i,m);j++)   //因为要连续砍所以 j<=min(i,m){//转移方程:j天砍 i-1棵树,第i棵不砍和在第j天砍第i棵树 dp[i][j]=max(dp[i-1][j],dp[i-1][j-1]+tree[i].a+tree[i].b*(j-1));}}cout<<dp[n][m]<<endl;}}



原创粉丝点击