洛谷 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;
}