hlg2146【多维背包】
复活 | ||||||
|
||||||
Description | ||||||
真希望海棠树下的约定能够存在,真希望那个乖巧的女孩还会提着行李抱着他买的超大轻松熊满怀希望安静地等待他的到来。 真希望穿着和服十二单的女孩可以依旧在他的面前傻得可爱的做提裙礼,而不是抱着对他的爱义无反顾选择坠入地狱。真希望黑郁金香一样的女孩还是沉默地站在他的身后,而不是站在高高的东京塔上对着路明非用敬语说谢谢,然后纵身越塔,如黑郁金香般凋零。真希望那个女孩还是可以如同很久之前一样让他背着一脚一脚踩过西伯利亚的冰雪,而不是膝盖受了重伤却一个人不吭一声用酒精消毒,不愿意让自己成为没有用的人。
绘梨衣理明非而去了…… 路明非想让他喜欢的那个女孩复活,然后陪着她哪怕一天。首先他需要达到一定得能力值,然后才能让那个一直都扯着他衣角亦步亦趋的跟在他后面的胆小女孩复活。路明非有一些试剂原料,可以调配出一些试剂,每注射一种试剂能让路明非增长一定的能力值但一生只能注射一次。 |
||||||
Input | ||||||
有多组测试数据。对于每组测试数据,第一行为n(1<=n<=100), m(1<=m<=5),表示可以调配n种试剂,有m种原料,第二行有m个数代表路明非拥有的每种原料的个数。接下来有n行,每行有m+1个非负整数,第一个为这种药剂能增长的能力值,剩下的m个数分别表示这种药剂需要的每种原料的个数。 | ||||||
Output | ||||||
每组测试数据输出一行,包含一个整数,表示获得的最大能力值。 | ||||||
Sample Input | ||||||
1 1
1 1 1 |
||||||
Sample Output | ||||||
1 |
这个题有两种做法
我喜欢用搜索来做
也就是说写dp的时候用递归来写
代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 7 #define sc scanf 8 #define pr printf 9 #define me(a, b) memset(a, b, sizeof(a)) 10 #define fr(i, j, k) for(int i = j; i <= k; i++) 11 #define re return 12 #define br break 13 #define co continue 14 15 const int maxn = 105; 16 const int maxm = 6; 17 18 int n, m; 19 int a[maxn][maxm]; 20 int dp[maxn][1005]; 21 22 int dfs(int x, int c[maxm]) { 23 int s1 = 0; 24 fr(i, 1, m) { 25 s1 += c[i] * ( i + 11 ) + i * i; 26 } 27 int xx = 0; fr(i, 1, m) xx += c[i]; 28 if(x == 0 || xx == 0) { 29 re dp[x][s1] = 0; 30 } 31 bool flag = true; 32 fr(i, 1, n) { 33 if(c[i] < a[x][i]) { 34 flag = false; 35 br; 36 } 37 } 38 int d[maxm]; 39 if(flag) { 40 fr(i, 1, m) d[i] = c[i] - a[x][i]; 41 re dp[x][s1] = max(dfs(x - 1, c), dfs(x - 1, d) + a[x][0]); 42 } else { 43 re dp[x][s1] = dfs(x -1, c); 44 } 45 } 46 47 int b[maxm]; 48 int main() { 49 while(EOF != sc("%d %d",&n, &m) ) { 50 fr(i, 1, m) { 51 sc("%d",&b[i]); 52 } 53 fr(i, 1, n) { 54 for(int j = 0; j <= m; j++) { 55 sc("%d",&a[i][j]); 56 } 57 } 58 memset(dp, -1, sizeof(dp)); 59 pr("%d\n", dfs(n, b)); 60 } 61 re 0; 62 }