881. 麦香牛块
★ 输入文件:nuggets.in
输出文件:nuggets.out
简单对比 时间限制:1 s 内存限制:128 MB
描述
农夫布朗的奶牛们正在进行斗争,因为它们听说麦当劳正在考虑引进一种新产品:麦香牛块。奶牛们正在想尽一切办法让这种可怕的设想泡汤。奶牛们进行斗争的策略之一是“劣质的包装”。“看,”奶牛们说,“如果你只用一次能装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 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 7 using namespace std; 8 #define N 70260 9 10 11 12 int main() 13 { 14 freopen("nuggets.in","r",stdin); 15 freopen("nuggets.out","w",stdout); 16 int dp[N]={0}; 17 int k[300]={0}; 18 int n; 19 int a; 20 cin>>n; 21 int i,j; 22 for(i=0;i<n;i++) 23 { 24 cin>>k[i]; 25 dp[k[i]]=1; 26 } 27 for(i=1;i<=70260;i++) 28 { 29 for(j=0;j<n;j++) 30 { 31 a=i-k[j]; 32 if(a<0)continue; 33 if(dp[a]==1){dp[i]=1;break;} 34 } 35 } 36 for(i=70000;i>0;i--) 37 if(dp[i]==0)break; 38 for(j=70001;j<70257;j++) 39 if(dp[j]==0)break; 40 if(j==70257)cout<<i<<endl; 41 else cout<<0<<endl; 42 return 0; 43 }
首先,经过证明如果存在最大的不能买到的块数,则这个块数最大不会超过70000所以建一个长度为70000的DP数组便可以了。 代码解析:
首先建立一个长度为300的数组S,对包装类型进行存储,然后是变量n表示包装类型的个数,再定义一个变量s表示最多所用的包装个数。然后对种类进行输入,再输入的同时将种类所对应的DP数组下标赋值为1;
然后从前向后将DP数组扫一遍。
扫DP数组的方法:
从第2个元素开始从前向后扫,从满足以下条件的元素中选出值最小的加1存入DP[i]中;
1、元素总数是下标是i—k[j],j从1到n;
2、i—k[j]要大于0;
3、下标i—k[j]所对应的DP数组元素,存储的数据小于s;
如果不存在这样的数则输出i;如果到最后全部扫完则证明所有元素都能组成;