神秘的石头(stone)
时间限制: 1000 ms 空间限制: 262144 KB
题目描述
今年的上海世博会上,神秘的中山馆门口有一个史前游戏,一块巨石上有一堆神秘的小石头和一个史前的天平,中山的小工作人员正在组织观众们玩一个小游戏——用一个天平和一些石头称出一个物体的重量,当然,每个小石头都是标示出了它的重量的。这个小游戏不仅挑战了小朋友们的智慧,还提供了很多小奖品,因此小朋友们玩得非常开心。小博也玩了两次,一次他用1个1克的石头和2个5克的石头,称出了一个重量为11克的物品;第二次他用2个10克的石头和3个1克的石头,称出了一个重量为17克的物品。你能想明白他是怎么称的吗?
聪明的小博继续想,如果给我一定数量的各种石头,我能够称出多少种物品的重量呢?于是他回家后,自己编写了一个程序解决,请你也编写一个程序解决这个问题。
输入
只有一行,共4个数字n1、n2、n3、n4,分别表示1克、2克、5克、10克的石头的数量。取值范围0<=n1,n2,n3,n4<=500。
输出
只有一个数据,由n1个1克的石头,n2个2克的石头,n3个5克的石头,n4个10克的石头,一共可以称出多少种重的物品的数量。
样例输入
1 0 0 1
样例输出
4
数据范围限制
对于50%的数据:0<=n1,n2,n3,n4<=100,另外50%的数据:0<=n1,n2,n3,n4<=500
提示
用1个1克的石头,1个10克的石头,一共可以称出4种不同的重,分别是:1、9、10、11。
思路
其实通过提示我们就能够发现这道题的奥秘了,这道题没有很复杂,但是又会有点难度。我们通过观察提示中的数字发现,实际上这道题就是让我们求几个数随意加减,每个数只能用一次,能够算出来多少个数?这道题我的第一个想法想法就是想要四重循环暴力求解,但没能够成功。最终我还是借鉴了别人的代码,学到了一个方法,这个方法就叫动态规划(dp)。虽说是学习到了,但我的实力还是不够啊,百度过后完全没搞清楚dp是个怎么回事。于是乎我就不管什么dp了,干脆就是学这道题的方法。
好了,讲了这么多,我们该回归正轨了。让我们看看AC代码吧!(详见注释) 👇👇👇
#include<bits/stdc++.h>
using namespace std;
int a[10],w[10]={0,1,2,5,10};//输入用的数组以及存储每种石头的重量的数组
int dp[100005],ans;//拿来查看每个重量是否能够被称出的的数组以及最终答案
int main(){
for(int i=1;i<=4;i++)//输入
cin>>a[i];
dp[0]=1;
for(int i=1;i<=4;i++){//第一个循环循环的内容是每种重量
for(int j=1;j<=a[i];j++){//第二个则是每种重量的石头的个数
for(int k=10000;k>=0;k--){//每个重量去试
if(dp[k]&&k+w[i]<=10000){
dp[abs(k+w[i])]=1;//加
dp[abs(k-w[i])]=1;//减
}
}
}
}
for(int i=1;i<=10000;i++){
if(dp[i])ans++;//遍历dp数组查找能够称出重量的数量
}
printf("%d",ans);//输出答案
return 0;
}
想必大家都已经看懂了吧,还有什么不懂请在留言区告诉我,我会一一解答。诚信做题,请勿抄袭!
(づ ̄3 ̄)づ╭❤~