题目描述
果农的花园里种着N棵果树。收获的季节终于来到了,果农决定,在接下来的M天时间里完成自己的收获工作。他的收获方式极其暴力——他将会将某棵果树砍倒来获取上面的果实。然而如此暴力的果农体力也十分有限,他每天最多只能砍一棵果树。已经知道,对于第i棵果树,在第1天的时候上面已经有ai个果实,而接下来每一天(不包括第1天),它都会再长出bi个果实(0<=ai,bi<=104,ai,bi均为整数)。果农只能获得砍下来的果树上的果实,而砍下来的果树将不会再长果实。果农想知道,自己在M天后最多可以收获多少个果实。
输入输出格式
输入格式:第1行包含两个整数N,M。
第2行N个数,用空格隔开,第i个数表示ai。
第3行N个数,用空格隔开,第i个数表示bi。
输出格式:一个数,表示最多能获得到的果实。
输入输出样例
输入样例#1:
2 2 8 10 2 3
输出样例#1:
21
说明
数据规模
对于30%的数据,0<M,N<=30;
对于100%的数据,0<M,N<=1000;
数据保证答案小于等于231-1。
/* dp 方程 到第j天的答案为max(第j天,第j-1天+初始天的数量+成长的数量) dp[j]=max(dp[j],dp[j-1]+fru[i].a+fru[i].b*(j-1)); 第m天为answer--dp[m] */ #include<iostream> #include<cstdio> #include<algorithm> using namespace std; int n,m,maxn=-1; struct Fruit{ int a,b; }fru[1005]; int dp[1005]; bool cmp(Fruit f1,Fruit f2) { if(f1.b==f2.b) { return f1.a>f2.a; } return f1.b>f2.b; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&fru[i].a); for(int i=1;i<=n;i++) scanf("%d",&fru[i].b); sort(fru+1,fru+1+n,cmp); for(int i=1;i<=n;i++) for(int j=m;j>=1;j--)//到第j天的答案为max(第j天,第j-1天+初始天的数量+成长的数量) dp[j]=max(dp[j],dp[j-1]+fru[i].a+fru[i].b*(j-1)); cout<<dp[m]<<endl;//第m天为answer return 0; }