1. 程式人生 > 實用技巧 >[Usaco2009 Oct]Bessie's Weight Problem 貝茜的體重問題

[Usaco2009 Oct]Bessie's Weight Problem 貝茜的體重問題

題目

Description

Bessie像她的諸多姊妹一樣,因為從Farmer John的草地吃了太多美味的草而長出了太多的贅肉。所以FJ將她置於一個及其嚴格的節食計劃之中。她每天不能吃多過H (5 <= H <= 45,000)公斤的乾草。 Bessie只能吃一整捆乾草;當她開始吃一捆乾草的之後就再也停不下來了。她有一個完整的N (1 <= N <= 500)捆可以給她當作晚餐的乾草的清單。她自然想要儘量吃到更多的乾草。很自然地,每捆乾草只能被吃一次(即使在列表中相同的重量可能出現2次,但是這表示的是兩捆乾草,其中每捆乾草最多隻能被吃掉一次)。 給定一個列表表示每捆乾草的重量S_i (1 <= S_i <= H), 求Bessie不超過節食的限制的前提下可以吃掉多少乾草(注意一旦她開始吃一捆乾草就會把那一捆乾草全部吃完)。

Input

* 第一行: 兩個由空格隔開的整數: H 和 N * 第2到第N+1行: 第i+1行是一個單獨的整數,表示第i捆乾草的重量S_i。

Output

* 第一行: 一個單獨的整數表示Bessie在限制範圍內最多可以吃多少公斤的乾草。

Sample Input

56 4
15
19
20
21

Sample Output

56

思路

很明顯是一道揹包題;

但是直接揹包模板是過不了的;會$TLE$;

只需要一個特判就ok了,如果已經背出了揹包的最大容量,那麼直接輸出最大容量,然後結束程式;

由於博主蒟蒻,非常喜歡快,所以就加了$bitset$ 優化;

程式碼

#include<bits/stdc++.h>
#define re register
typedef long long ll;
using namespace std;
inline ll read()
{
    ll a=0,f=1; char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
    return a*f;
}
ll n,m;
ll a[
6010]; bitset<50010> dp;//bitset的定義 int main() { dp[0]=1;//初始化,沒它,你wa m=read(); n=read(); for(re ll i=1;i<=n;i++) { a[i]=read(); dp|=(dp<<a[i]); if(dp[m])//特判 { printf("%lld\n",m); return 0; } } for(re ll i=m;i>=1;i--) if(dp[i])//逆迴圈,找到最大的權值 { printf("%lld\n",i); break; } //return 0; }