誠勤立達到重慶市旅遊見到了黃金樹,黃金樹上天天會結出金子。已經有n棵樹,誠勤立達要停留m天,天天只能砍掉一棵樹,砍掉樹後就能獲得樹上的黃金。給定n棵樹上原有的黃金a[i]和每棵樹天天能夠新增長的黃金b[i],求他最多能夠獲得多少黃金。中途若是有1天不砍樹的話,以後的日子就不能砍樹,全部最好天天都砍樹,或者直到樹被砍完。node
輸入格式
第一行:一個正整數T,表明樣例個數。spa
對於每個樣例包含3行:code
第一行:n 和 m(0 < m <= n <= 250), 以空格分開。get
第二行:n個正整數,以空格隔開(0 < ai <= 100, i=1, 2, 3...n)。string
第三行:n個整數,以空格隔開 (0 < bi <= 100, i=1, 2, 3...n) 。it
輸出格式
對於每個樣例,輸出每一個輸出。io
樣例
樣例輸入
2
2 1
10 10
1 1
2 2
8 10
2 3
樣例輸出
10
21sort
咱們老師彷佛絕對是改了某道題題面,但沒看出來,知道原題的在下面評論一下,謝謝qwqdi
好神奇的一道0/1揹包,就是一個哲學的等號出了鍋,調了40minwhile
#include <cstdio> #include <cstring> #include <algorithm> 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; }