本章目录
[USACO09OCT] Bessie’s Weight Problem G
题目描述
Bessie 像她的诸多姊妹一样,因为从 Farmer John 的草地吃了太多美味的草而长出了太多的赘肉。所以 FJ 将她置于一个及其严格的节食计划之中。她每天不能吃多过 H ( 5 ≤ H ≤ 45 , 000 ) H (5 \le H \le 45,000) H(5≤H≤45,000) 公斤的干草。 Bessie 只能吃一整捆干草;当她开始吃一捆干草的之后就再也停不下来了。她有一个完整的 N ( 1 ≤ N ≤ 500 ) N (1 \le N \le 500) N(1≤N≤500) 捆可以给她当作晚餐的干草的清单。她自然想要尽量吃到更多的干草。很自然地,每捆干草只能被吃一次(即使在列表中相同的重量可能出现2次,但是这表示的是两捆干草,其中每捆干草最多只能被吃掉一次)。 给定一个列表表示每捆干草的重量 S i ( 1 ≤ S i ≤ H ) S_i (1 \le S_i \le H) Si(1≤Si≤H) , 求 Bessie 不超过节食的限制的前提下可以吃掉多少干草(注意一旦她开始吃一捆干草就会把那一捆干草全部吃完)。
输入格式
第一行有两个由空格隔开的整数 H H H 和 N N N。
第 2 2 2 到第 N + 1 N+1 N+1 行,第 i + 1 i+1 i+1 行是一个单独的整数,表示第 i i i 捆干草的重量 S i S_i Si。
输出格式
第一行一个单独的整数表示 Bessie 在限制范围内最多可以吃多少公斤的干草。
样例 #1
样例输入 #1
56 4
15
19
20
21
样例输出 #1
56
提示
输入说明
有四捆草,重量分别是 15 , 19 , 20 15,19,20 15,19,20 和 21 21 21。Bessie 在 56 56 56 公斤的限制范围内想要吃多少就可以吃多少。
输出说明
Bessie 可以吃 3 3 3 捆干草(重量分别为 15 , 20 , 21 15, 20, 21 15,20,21)。恰好达到她的 56 56 56 公斤的限制。
题意
题意:给你一个上限 h h h和 n n n个数 S 1 , S 2 , . . . , S n S_1,S_2,...,S_n S1,S2,...,Sn,让你在不超过h的情况下选出若干个数,使得这几个数的和最大。
题解
很明显不能使用贪心,样例就是一个明证。于是想到DP。
由题目可知每捆干草可选可不选,每捆干草只有一捆(虽然是废话,但它告诉我们不是多重背包),有上限 h h h。综合分析,01背包问题属实。
状态表示
设f[i,j]
表示前i个物品容量为j时最多能get多少重量的干草。压维后f[j]
表示容量为j时最多能get多少重量的干草。
01背包的上限为h
01背包物品的价值为 S i S_i Si,代价为 S i S_i Si
状态转移方程
跟景点01背包的状转差唔多: f j = max { f j , f j − w [ i ] + w [ i ] } f_j=\max\{f_j,f_{j-w[i]}+w[i]\} fj=max{fj,fj−w[i]+w[i]}
max里的内容:
前者是不选的情况,后者是选的情况。
code (用w[i]替换s[i])
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
const int N=505;
const int H=45005;
int h,n;
int w[N];//干草的重量
int f[H];
int main(){
cin>>h>>n;
for(int i=1;i<=n;i++)cin>>w[i];
for(int i=1;i<=n;i++){
for(int j=h;j>=w[i];j--){
f[j]=max(f[j-w[i]]+w[i],f[j]);
}
}
cout<<f[h];
return 0;
}
总结
本文介绍了USACO09OCT比赛中的一道题目:Bessie’s Weight Problem G。题目要求在不超过给定上限H的情况下,选取若干个干草捆,使得总重量最大。题目可以通过01背包算法解决。
首先,我们定义了状态表示和状态转移方程,其中f[i,j]表示前i个物品容量为j时最多能get多少重量的干草。然后,我们使用了跟01背包一样的状态转移方程,通过遍历所有物品,对于每个物品,我们都尝试将它加入到背包中,如果加入后背包总重量不超过H,那么我们就能够获得更多的干草重量。
最后,我们输出了在不超过H的情况下,Bessie最多可以吃多少公斤的干草。
这道题目主要考察了对于01背包问题的理解和应用,以及编程实现的能力。通过本题,我们可以加深对于01背包问题的理解,并学会如何将其应用到实际问题中。同时,我们也可以通过编程实现这个过程,从而解决实际问题。