首页 > 分享 > DP解决摇钱树问题

DP解决摇钱树问题

P1987 摇钱树

最新推荐文章于 2024-11-19 23:59:35 发布

weixin_30279315 于 2018-09-02 14:22:00 发布

题意:有n棵摇钱树,k天,每天可砍一棵并获得其金币

      每棵树初始有$a_i$个金币,每天减少$b_i$个

   问k天得到的最多金币数

这题很明显是DP(锻炼自己的机会来了QAQ)

设$f[i][j]$代表前i棵数,到第j天所得最大值

$f[i][j]=max(f[i-1][j],f[i-1][j-1]+a[i]-(j-1)*b[i])$   666

但是跑完样例发现

f[3][2]=44

f[3][3]=43!!!

what???

咋多了一天答案反而减少了??

输出DP过程,发现$a[i]-(j-1)*b[i]$可能是负的!!

但实际上一棵树不可能有负数个金币

所以判断若是负数让其等于0

这还不够,f[3][3]=44.......应该是47

假设我们有3棵树且要选全部,每棵价值和每次消耗分别为$m1,m2,m3;b1,b2,b3;$则$总价值=m1+m2+m3-k1*b1-k2*b2-k3*b3$,

很明显我们要选消耗大的啊  

所以排序后,47自然就出来了qaq

#include<cstdio> #include<iostream> #include<cstring> #include<cctype> #include<algorithm> using namespace std; #define int long long #define olinr return #define _ 0 #define love_nmr 0 #define DB double int n; int k; struct node { int num; int down; friend bool operator < (const node &a,const node &b) { return a.down>b.down; } }a[1050]; inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) { if(ch=='-') f=-f; ch=getchar(); } while(isdigit(ch)) { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } inline void put(int x) { if(x<0) { x=-x; putchar('-'); } if(x>9) put(x/10); putchar(x%10+'0'); } int f[1050][1050]; signed main() { while(5201314) { n=read(); k=read(); if(!n&&!k) break; memset(f,0,sizeof f); for(int i=1;i<=n;i++) a[i].num=read(); for(int i=1;i<=n;i++) a[i].down=read(); sort(a+1,a+n+1); for(int j=1;j<=k;j++) for(int i=1;i<=n;i++) { int x=a[i].num-(j-1)*a[i].down; x=x>0? x:0; f[i][j]=max(f[i-1][j],f[i-1][j-1]+x); } int ans=0; for(int i=1;i<=n;i++) ans=max(ans,f[n][i]); put(ans); putchar('n'); } olinr ~~(0^_^0)+love_nmr; } /* 3 3 10 20 30 4 5 6 0 0 4 3 20 30 40 50 2 7 6 5 */

转载于:https://www.cnblogs.com/olinr/p/9573734.html

相关知识

「DP节油剂」“爱车”=毁车,你最关心的燃油添加剂问题来了!
dp练习题1
动态规划解决花店橱窗布置问题
古韵之乞巧 题解 dp题
木板切割问题算法
花店橱窗(线性dp)
[线性dp]花店橱窗 AcWing313
养殖摇钱树
摆花 (DP动态规划)
摇钱树怎么养护

网址: DP解决摇钱树问题 https://m.huajiangbk.com/newsview2310394.html

所属分类:花卉
上一篇: 摇钱树烂根怎么办,摇钱树烂根的补
下一篇: 使用递归解决摇钱树问题