[题目解析]神秘的石头

神秘的石头(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 ̄)づ╭❤~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值