刚开始没有思路,后来发现如果已经知道要砍哪m棵,那么这m棵的最优方案就是先砍b小的(贪心)。
于是把树按b排序后,再动态规划。其实这题可以更难点,就是m可能大于n。虽然后来发现了n>=m...
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=260;
int dp[N][N];//前i棵砍了j棵的最大
struct tree{
int a,b;
}t[N];
int cmp(tree a,tree b){
return a.b<b.b;
}
int main(){
int tt,n,m;
scanf("%d",&tt);
while(tt--){
scanf("%d %d",&n,&m);
for(int i=0;i<n;i++)
scanf("%d",&t[i].a);
for(int i=0;i<n;i++)
scanf("%d",&t[i].b);
sort(t,t+n,cmp);
int wait=m-n;
if(wait>0)
m=n;
else wait=0;
memset(dp,0,sizeof dp);
for(int i=0;i<n;i++){
for(int j=0;j<=m;j++){
dp[i+1][j+1]=max(dp[i+1][j+1],dp[i][j]+t[i].a+t[i].b*(j+wait));//砍
dp[i+1][j]=max(dp[i+1][j],dp[i][j]);//不砍
}
}
printf("%d\n",dp[n][m]);
}
return 0;
}