诚勤立达到重庆市旅游见到了黄金树,黄金树上每天会结出金子。已经有n棵树,诚勤立达要停留m天,每天只能砍掉一棵树,砍掉树后就能得到树上的黄金。给定n棵树上原有的黄金a[i]和每棵树每天可以新增加的黄金b[i],求他最多可以得到多少黄金。中途如果有1天不砍树的话,之后的日子就不能砍树,所有最好每天都砍树,或者直到树被砍完。
输入格式
第一行:一个正整数T,代表样例个数。
对于每一个样例包含3行:
第一行:n 和 m(0 < m <= n <= 250), 以空格分开。
第二行:n个正整数,以空格隔开(0 < ai <= 100, i=1, 2, 3...n)。
第三行:n个整数,以空格隔开 (0 < bi <= 100, i=1, 2, 3...n) 。
输出格式
对于每一个样例,输出每个输出。
样例
样例输入
2
2 1
10 10
1 1
2 2
8 10
2 3
样例输出
10
21
我们老师似乎绝对是改了某道题题面,但没看出来,知道原题的在下面评论一下,谢谢qwq
好神奇的一道0/1背包,就是一个哲学的等号出了锅,调了40min
Code
#include
#include
#include
using namespace std;
const int MAXN = 5005;
inline int read() {
int k = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
k = (k << 1) + (k << 3) + (ch & 15);
ch = getchar();
}
if (f == -1) k = ~k + 1;
return k;
}
inline void write(int x) {
if (x < 0)
x = -x, putchar('-');
if (x > 9)
write(x / 10);
putchar(x % 10 + '0');
}
int m,n,dp[MAXN][MAXN];
struct node{
int v,w;
}a[MAXN];
int max_(int x){
if (x - 1 >= 0) return x - 1;
else return 0;
}
bool cmp(node x,node y){
return x.v < y.v;
}
int main(){
//int t = read();
int t;
scanf("%d",&t);
while(t--){
//m = read(),n = read();
scanf("%d %d",&n,&m);
for (int i = 1 ; i <= n ; i++){
scanf("%d",&a[i].w);
for (int j = 1 ; j <= m ; j++) dp[i][j] = 0;
}
for (int i = 1 ; i <= n ; i++) scanf("%d",&a[i].v);
sort(a + 1,a + 1 + n,cmp);
for (register int i = 1 ; i <= n ; i++){
for (register int j = 1 ; j <= m ; j++){
if (dp[i - 1][j] > dp[i - 1][j - 1] + a[i].v * max_(j) + a[i].w) dp[i][j] = dp[i - 1][j];
else dp[i][j] = dp[i - 1][j - 1] + a[i].v * max_(j) + a[i].w;
}
}
if (t != 0) printf("%d\n",dp[n][m]);
else printf("%d",dp[n][m]);
}
return 0;
}