思路:增长速度快的只有放在后面砍才能获得最大的收益。
dp[i][j]表示从前i棵树中选出j棵树, 在前j天砍,砍得顺序就是排序的顺序
#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
int T;
int n, m;
int dp[300][300];
pair<int,int> p[300];
void init(){
memset(dp, 0, sizeof(dp));
}
int main(){
scanf("%d", &T);
while(T--){
init();
scanf("%d%d", &n, &m);
for(int i=1; i<=n; i++)
scanf("%d", &p[i].second);
for(int i=1; i<=n; i++)
scanf("%d", &p[i].first);
sort(p+1, p+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]+p[i].first*(j-1)+p[i].second);//表示(前i-1棵树取j棵) 和(前i-1棵树取j-1棵与第j棵树的和)二者之间的最大值
}
}
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
printf("%d ", dp[i][j]);
puts("");
}
printf("%d\n", dp[n][m]);
}
return 0;
}