Codeforces 922 E Birds (背包dp)被define坑了的一题
网页链接:点击打开链接
Apart from plush toys, Imp is a huge fan of little yellow birds!

To summon birds, Imp needs strong magic. There are n trees in a row on an alley in a park, there is a nest on each of the trees. In the i-th nest there are ci birds; to summon one bird from this nest Imp needs to stay under this tree and it costs him costi points of mana. However, for each bird summoned, Imp increases his mana capacity by B points. Imp summons birds one by one, he can summon any number from 0 to ci birds from the i-th nest.
Initially Imp stands under the first tree and has W points of mana, and his mana capacity equals W as well. He can only go forward, and each time he moves from a tree to the next one, he restores X points of mana (but it can't exceed his current mana capacity). Moving only forward, what is the maximum number of birds Imp can summon?
The first line contains four integers n, W, B, X (1 ≤ n ≤ 103, 0 ≤ W, B, X ≤ 109) — the number of trees, the initial points of mana, the number of points the mana capacity increases after a bird is summoned, and the number of points restored when Imp moves from a tree to the next one.
The second line contains n integers c1, c2, ..., cn (0 ≤ ci ≤ 104) — where ci is the number of birds living in the i-th nest. It is guaranteed that
.
The third line contains n integers cost1, cost2, ..., costn (0 ≤ costi ≤ 109), where costi is the mana cost to summon a bird from the i-th nest.
Print a single integer — the maximum number of birds Imp can summon.
2 12 0 4
3 4
4 2
6
4 1000 10 35
1 2 4 5
1000 500 250 200
5
2 10 7 11
2 10
6 1
11
In the first sample base amount of Imp's mana is equal to 12 (with maximum capacity also equal to 12). After he summons two birds from the first nest, he loses 8 mana points, although his maximum capacity will not increase (since B = 0). After this step his mana will be 4 of 12; during the move you will replenish 4 mana points, and hence own 8 mana out of 12 possible. Now it's optimal to take 4 birds from the second nest and spend 8 mana. The final answer will be — 6.
In the second sample the base amount of mana is equal to 1000. The right choice will be to simply pick all birds from the last nest. Note that Imp's mana doesn't restore while moving because it's initially full.
题目大意:一共有n棵树,刚开始有w元,第i棵树上有nb[i]只鸟,第i棵树上的鸟要花c[i]元,每走一棵树增加x元,每买一个鸟会让钱包容量增加b,问最多能买到几只鸟?
解法:背包dp,不过这题要根据数据范围选好下标,下标不能是1e9的钱数,dp的值不能是鸟数,鸟数可以用来当成下标
dp[i][j]表示走到第i棵树下,这时候已经买了j只鸟,剩下的钱数,dp[i][j] = max{dp[i-1][j - k] - k * c[i-1] + x}
坑点:每次更新dp[i][j]的时候钱不能超过钱包容量,而且要算出买几只鸟能让dp[i][j]最大,所以用了个嵌套的max,min,但是!!我居然学别人在开头define了max和min,导致嵌套了个寂寞,以后要么自己定义函数,要么直接用algorithm中的max,别再define了!
代码里还是有蛮多细节技巧的,仔细看看
#include<cstdio>
#include<cstring>
#include<algorithm>
//#define min(a, b) a>=b?b:a //←罪魁祸首!!!
//#define max(a, b) a>=b?a:b //←你也是!!!!
typedef long long ll;
using namespace std;
const int maxn = 1000 + 100;
const int maxw = 10000 + 100;
ll c[maxn], nb[maxw];
ll dp[maxn][maxw];//dp[i][j]表示走到第i棵树下,这时候已经买了j只鸟,剩下的钱数
//dp[i][j] = max{dp[i-1][j - k] - k * c[i-1] + x}
int main(){
ll n, w, b, x;//走一棵树加x钱,买一只鸟增加容量b;
scanf("%lld %lld %lld %lld", &n, &w, &b, &x);
int mana = w, max_mana = w;
for(int i = 0; i < n; i++) scanf("%d", &nb[i]);
for(int i = 0; i < n; i++) scanf("%d", &c[i]);
ll sum = 0;
memset(dp, -1, sizeof(dp));//最后还为-1的dp就是不可能达到的
dp[0][0] = w;//当i等于0的时候,即在第一棵树下的时候,这时候一只鸟都没买,所以当i=0时只有j=0这种情况
for(int i = 1; i <= n; i++){//从刚到第二棵树下开始循环(正在第二颗树下,还没决定在第二颗树买几只鸟)
sum += nb[i-1];//此时站在第i棵树下,最多买了sum只鸟,也就是前面的全买了
for(int j = 0; j <= sum; j++){
for(int k = 0; k <= nb[i-1] && k <= j ; k++){//这个循环用来解决dp[i][j]的最大值能是多少
if(dp[i-1][j-k] == -1){/*printf("j = %d, k = %d, dp[%d][%d] = %d\n", j, k, i-1, j-k,dp[i-1][j-k]);*/continue;}
if(dp[i-1][j-k] - k * c[i-1] < 0 ) {/*printf("nonono!\nk = %d, j = %d\n", k, j);*/continue;}//没钱了, 这时候还没走到下一棵树,所以不要加x
dp[i][j] = max(dp[i][j], min(dp[i-1][j-k] - k*c[i-1] + x, w + j * b));//更新最大的dp,同时注意钱包的上限
//printf("dp[i-1][j-k] - k*c[i-1] + x为%d\n此时w+j*b为%d, dp[%d][%d]应该为%d\n", dp[i-1][j-k] - k*c[i-1] + x,w+j*b, i, j, min(dp[i-1][j-k] - k*c[i-1] + x, w + j * b));
}
//printf("dp[%d][%d] = %d, sum = %d\n", i, j, dp[i][j], sum);
}
}
ll ans;
for(int i = 0; i <= sum; i++)
if(dp[n][i] != -1) ans = i;
printf("%lld\n", ans);
return 0;
}
Codeforces 922 E Birds (背包dp)被define坑了的一题的更多相关文章
- Codeforces 864E Fire(背包DP)
背包DP,决策的时候记一下 jc[i][j]=1 表示第i个物品容量为j的时候要选,输出方案的时候倒推就好了 #include<iostream> #include<cstdlib& ...
- Codeforces Codeforces Round #319 (Div. 2) B. Modulo Sum 背包dp
B. Modulo Sum Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/577/problem/ ...
- Codeforces 730J:Bottles(背包dp)
http://codeforces.com/problemset/problem/730/J 题意:有n个瓶子,每个瓶子有一个当前里面的水量,还有一个瓶子容量,问要把所有的当前水量放到尽量少的瓶子里至 ...
- Codeforces 946 课程表背包DP 数位DFS构造
A B 给你A,B 两个数 1.a=0 OR b=0 break 2.a>=2b a=a-2b 3.b>=2a b=b-2a 如果只是单纯模拟肯定会超时 ...
- Educational Codeforces Round 69 (Rated for Div. 2) D. Yet Another Subarray Problem 背包dp
D. Yet Another Subarray Problem You are given an array \(a_1, a_2, \dots , a_n\) and two integers \( ...
- 背包dp整理
01背包 动态规划是一种高效的算法.在数学和计算机科学中,是一种将复杂问题的分成多个简单的小问题思想 ---- 分而治之.因此我们使用动态规划的时候,原问题必须是重叠的子问题.运用动态规划设计的算法比 ...
- G - Surf Gym - 100819S -逆向背包DP
G - Surf Gym - 100819S 思路 :有点类似 逆向背包DP , 因为这些事件发生后是对后面的时间有影响. 所以,我们 进行逆向DP,具体 见代码实现. #include<bit ...
- luogu 4377 Talent show 01分数规划+背包dp
01分数规划+背包dp 将分式下面的部分向右边挪过去,通过二分答案验证, 注意二分答案中如果验证的mid是int那么l=mid+1,r=mid-1,double类型中r=mid,l=mid; 背包dp ...
- bzoj1625:[Usaco2007 Dec]宝石手镯(背包dp板子)
1625: [Usaco2007 Dec]宝石手镯 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1349 Solved: 954[Submit][St ...
随机推荐
- MD5:js,java,C#三种语言加密结果不同解决办法
最近遇到前端js MD5加密与后端C#与Java MD5加密结果不一致的问题,所以写个关于此问题的解决办法 前端js引用的md5类库,类库地址:https://blueimp.github.io/Ja ...
- c++ beep 演奏一次质量不高的天空之城
beep函数用法: beep(HZ,time); hz是发出多少赫兹声音,time是发声时间(ms) 话不多说,上代码 #include <cstdio> #include <win ...
- linux文件通配符
* #匹配任意字符 ? #匹配任意单个字符 ~ #当前用户家目录 ~user #用户user的家目录 ~+ #当前工作目录 ~- #前一个工作目录 [0-9] #匹配的数字范围 [a-z] #匹配小写 ...
- Asp.Net Core 学习教程1、初始.Net Core与VS Code 第一个web程序
1..Net Core介绍 .NET Core是.NET Framework的新一代版本, 是微软开发的第一个具有跨平台(Windows.Macosx.Linux) 能力的应用程序开发框架,未来也将会 ...
- python 枚举类型
在python中枚举是一种类(Enum,IntEnum),存放在enum模块中.枚举类型可以给一组标签赋予一组特定的值. 枚举的特点: 枚举类中不能存在相同的标签名 枚举是可迭代的 不同的枚举标签可以 ...
- 【Tool】---SVN的超级简单并具体得使用介绍
又一次被打脸,笔者表示再也不相信自己的记性了.简单的SVN隔了一段时间后,由于项目的需要要重新简历代码库,竟然一下子又忘了.天那,这就好比战士上了战场发现没带枪,这能行吗?因此,趁着今天又简短的复习了 ...
- 【LC_Overview1_5】---学会总结回顾
刷LeetCode题目一周,主要采用C++和Python编程手段,截至目前做了5道简单的leetcode题目,做下阶段性的小结: 小结主要通过手撕代码,复习加回顾,尽量避免自己眼高手低的情况发生,对于 ...
- React Context 的用法
在React的官方文档中,Context被归类为高级部分(Advanced),属于React的高级API,但官方并不建议在稳定版的App中使用Context. The vast majority of ...
- Flask蓝图(Blueprint)
一.作用 1.目录结构划分 2.url添加前缀 url_prefix 3.应用特殊装饰器,在该蓝图定义的特殊装饰器,只在改蓝图的起效 二.简单示例 1.创建一个项目文件 2.创建一个同名的python ...
- 7.JavaSE之类型转换
类型转换: 由于Java是强类型语言,所以要进行运算的时候,需要用到类型转换. 图中优先级从低到高,小数优先级大于整数. 运算中,不同类型的数据需要转换为同一类型,然后进行运算. 强制类型转换:(类型 ...