洛谷 P2737 [USACO4.1]麦香牛块Beef McNuggets

洛谷 P2737 [USACO4.1]麦香牛块Beef McNuggets

题目描述

农夫布朗的奶牛们正在进行斗争,因为它们听说麦当劳正在考虑引进一种新产品:麦香牛块。奶牛们正在想尽一切办法让这种可怕的设想泡汤。奶牛们进行斗争的策略之一是“劣质的包装”。“看,”奶牛们说,“如果你只用一次能装3块、6块或者10块的三种包装盒包装麦香牛块,你就不可能满足一次只想买1、2、4、5、7、8、11、14或者17块麦香牛块的顾客了。劣质的包装意味着劣质的产品。”

你的任务是帮助这些奶牛。给出包装盒的种类数N(1<=N<=10)和N个代表不同种类包装盒容纳麦香牛块个数的正整数(1<=i<=256),输出顾客不能用上述包装盒(每种盒子数量无限)买到麦香牛块的最大块数。如果所有购买方案都能得到满足或者不存在不能买到块数的上限,则输出0。 不能买到的最大块数(倘它存在)不超过2,000,000,000。

输入输出格式
输入格式:

第1行: 包装盒的种类数N

第2行到N+1行: 每个种类包装盒容纳麦香牛块的个数

输出格式:

输出文件只有一行数字:顾客不能用包装盒买到麦香牛块的最大块数或0(如果所有购买方案都能得到满足或者顾客不能买到的块数没有上限)。

输入输出样例
输入样例#1:

3
3
6
10

输出样例#1:

17

思路

该题要求解所给的物品不能恰好放入的背包大小的最大值可能不存在,它的模型显然是多重背包。只需要根据“若 i、j 互质,则关于 x、y 的不定方程 ix+yj=n必有正整数解,其中 n>i*j”这一定理得出一个循环的上限,再套用多重背包模板即可。

特别需要注意的是,不能恰好放入的背包大小的最大值可能不存在,这时需要输出0。

代码如下:

#include <bits/stdc++.h>
using namespace std;

const int MAXN=15;
const int MAXM=720000;
int n,w[MAXN],dp[MAXM];

inline int read()
{
    int X=0; bool flag=1; char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}
    while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+(ch^'0'); ch=getchar();}
    if(flag) return X;
    return ~(X-1);
}

int main()
{
    n=read();
    for(int i=1;i<=n;++i)
        w[i]=read();
    dp[0]=1;
    for(int i=1;i<=n;++i)
    {
        if(dp[w[i]]) continue;
        for(int j=0;j<=700000;++j)
            if(dp[j]) dp[j+w[i]]=1;		
    }
    for(int i=700000;i>=0;--i)
        if(!dp[i])
        {
        	if(i>65024) printf("0");
        	else printf("%d",i);
        	return 0;
        }
    printf("0");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值