正经·DP题解

一道非常好的背包练手题(

sto(注:原思路来源 SLYZ_0120 的题解)orz

开始这道题

1.输入六个数,存进数组中
2.初始化 f 数组为0。 f [ i ] 表示重量为 i 的情况是否出现过(下面代码使用的是 int 数组,当然用 bool 数组会更好)。如果出现过即为真(1),未出现过即为假(0)。
3.这里我们要将 f [ 0 ] 设为 1 。总重量为 0 即一个砝码也不用,我们将这种情况设为已有。
4.第一重循环。

for (int i = 1 ; i <= 6 ; i++ )
我们枚举六种重量的砝码。

5.第二重循环

for (int j = 1 ; j <= a[i] ; j++ )
这里的a[i]指的是第 i 种砝码的个数。即我们进行循环的次数就是第i种砝码的个数(你是不是觉得我在说废话 但是请好好理解)

6.第三重循环

for (int k = 1000 ; k >= 0 ; k-- )
三重循环分开来或许不是很好理解。接下来我们来结合三个循环分析。

7.代码核心
for (int i=1 ; i<=6 ; i++)for (int j=1 ; j<=a[i] ; j++)for (int k=1000 ; k>=0 ; k--){if (f[k]==1){f[k+w[i]]=1;}}

请按照提示看以上代码

1.首先,请简要看完三重循环并尝试初步理解。

2.看循环内部语句。

       看这两个语句时,请尝试将样例代入(建议自己设个稍微大一点点点点的样例 真的大一点点就够了 因为 1 不够特殊),从 i=1,j=1,k=1000的情况开始,尝试想想,当是这种情况时, f 数组发生了什么变化?接着想想,当k不停的自减,会发生什么呢?最后想想,当 i=1,j=1,k=0的时候会发生什么呢?那又代表了什么意思?思考:循环内部的语句。接下来,我们指的“某种重量成立”,指的是这个重量可以被称出来。(也可以说,有这么一些砝码可以组成这个重量)其实,当六种砝码的个数都是无限的时候,因为我们有一种砝码的重量为1,所以所有重量都可以 成立 。但是,当六种砝码的个数是有限的时候,并不是所有的重量都能够 成立 。那么,我们的 f 数组,其实就是用于标记  “这种重量是否成立”  。我们有这么一个状态 X , 状态 X 的砝码重量为 w 。(即重量 w 成立)那么如果我们有一个 “未使用” 的砝码 ,其重量为 p ,那么重量   w+p    也是成立的。(这句话请认真理解)带着这个思路,请看向循环  “k=1000……” 以及 循环内部的语句  。这里的 k ,其实就是刚刚所提到的重量 w 。f [ k ] == 1 ,就是重量 k 成立的意思 。那么我们加上 w [ i ]  (相当于刚刚的 p ),即第i种砝码的重量,那么得到的重量依然是成立的。

3.请看向第二个循环语句

        顺着我们上一条的思路。返回我们文章开头的地方,对于 j 这重循环的介绍。“这里的 a [ i ] 指的是第 i 种砝码的个数。即我们进行循环的次数就是第i种砝码的个数”。接着看向我们上一条中“ 如果我们有一个 ‘未使用’ 的砝码 ”其实在我们进行这一重循环的时候,就相当于,我们将第 i 种砝码 “摆成一排”。对,你现在可以打大开脑洞,想着你本来有10个一样重的砝码,然后你把这些砝码在你面前整齐de放成一排——————现在拿起你的第一个砝码。我们开始找已知的 “成立的重量”。 找到一个成立的重量后,我们就可以确定,这个成立的重量加上你手中的这个砝码也是一个成立的重量。那么我们将新的 “成立的重量” 标记。现在拿起你的第二个砝码。我们继续找已知的 “成立的重量”。 注意,这时成立的重量,包含了我们刚刚拿第一个砝码时标记的 “新的成立的重量”。接下来的步骤类似上面。………………刚刚的砝码用完了,接着,你又拿出了跟刚才不同重量的另外10个一样重的砝码,摆成一排……接下来发生了什么也类似上面。当你把所有的砝码都用完的时候,所有被标记的 “成立的重量”,就是使用这些砝码的所有 “成立的重量” !最后,只要一遍扫过去 ~ 统计有多少种成立的重量就可以啦 ~

4.请思考:为什么 k 要从 1000 到 1 而不是 1 到 1000 呢?

        如果这个问题你一下子想不明白,那你可以先试着将下面的完整代码复制,把 for (int k=1000;k>=0;k--) 改成 for (int k=0;k<=1000;k++) ,再测一下样例,看一下结果是多少。如果你还没想清楚:惊不惊喜!意不意外!答案居然是1000!以样例为例子,我们可以想到,当 k=0 的时候, f[1] 就会被标记为成立。但接下来,当 k=1 的时候,f [2] 也会被标记为成立。那么是不是一遍扫过去,f [1~1000] 全部都被标记为成立了呢!在本题中,对于一个成立的重量 w ,一个砝码的重量 p ,w+p 一定大于 w。所以这样就会造成    一个砝码使用多次的情况  (请认真体会就是我们前一条所说的 “当六种砝码的个数都是无限的时候,因为我们有一种砝码的重量为1,所以所有重量都可以 成立 。”

完整代码

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const int MAXN=1001;
int a[7],w[7]={0,1,2,3,5,10,20},f[MAXN]={};//a数组存放的是每种砝码的数量,w数组是每种砝码的重量,f[i]表示 “重量 i 成立”
int main()
{for (int i=1;i<=6;i++)//输入{scanf("%d",&a[i]);}f[0]=1;//初始化!   f [0] 就是不使用任何砝码的情况for (int i=1;i<=6;i++)//枚举六种砝码{for (int j=1;j<=a[i];j++)//枚举每个砝码{for (int k=1000;k>=0;k--)//寻找 已成立的重量{if (f[k])//若此重量成立{f[k+w[i]]=1;//那么这个重量加上这个未使用的砝码的总重量也成立}}}}int ans=0;for (int i=1;i<=1000;i++)//一遍扫,统计成立的重量。记住从1开始循环,因为不使用砝码的情况在这里不统计{if (f[i]) ans++;}printf("Total=%d",ans);//输出return 0;//华丽丽de结束!} 

给大佬们递AC!!

转载于:https://www.cnblogs.com/Kan-kiz/p/10625584.html

【题解】Luogu P2347 砝码称重相关推荐

  1. 洛谷 P2347 砝码称重

    P2347 砝码称重 题目描述 设有1g.2g.3g.5g.10g.20g的砝码各若干枚(其总重<=1000), 输入输出格式 输入格式: 输入方式:a1 a2 a3 a4 a5 a6 (表示1 ...

  2. 洛谷P2347 砝码称重 某一年noip提高组原题

    可以转化为01背包求方案数的问题,dp数组f[][]表示第几个砝码能称出的重量,可压缩至一维 转移方程为f(i,j)+=f(i-1,j-w[i]) 当前我们可以称出的重量必定是由之前的砝码重量转移过来 ...

  3. 第十二届蓝桥杯省赛 Java 大学 B 组—砝码称重—满分百分题解

    第十二届蓝桥杯省赛 Java 大学 B 组-砝码称重-满分百分题解 一.解题思路 1.解法一( Java ) 解法思路:简单模拟 ☝ArrayList 遍历 + HashSet 存储(去重) 伪代码如 ...

  4. 【题解】【蓝桥杯】试题 历届真题 砝码称重【第十二届】【省赛】【B组】

    题目链接 试题 历届真题 砝码称重[第十二届][省赛][B组] 题目描述 解题思路 暴力,两个map,分别存储当前能称出的重量和遍历时用于计算的重量 需要注意的三点是 abs函数是在math.h里面的 ...

  5. 【codevs2144】砝码称重2,哈希什么的都去死吧

    砝码称重 2 时间限制: 1 s 空间限制: 16000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 有n个砝码,现在要称一个质量为m的物体,请问最少需要挑出几个 ...

  6. 第十二届蓝桥杯省赛 C/C++大学B组 试题G:砝码称重

    试题题目: 本题为编程题第二题 解题思路: 方法一:暴力求解 1.分析    首先利用数组W[N]W[N]W[N]记录NNN块砝码的质量.    模拟放取过程.先取第一块砝码放在天平上,再取第二块砝码 ...

  7. 第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-936 砝码称重

    第十四届蓝桥杯集训--练习解题阶段(无序阶段)-ALGO-936 砝码称重 目录 第十四届蓝桥杯集训--练习解题阶段(无序阶段)-ALGO-936 砝码称重 前言 关于数学的疑问 算法训练 砝码称重 ...

  8. 【DP】砝码称重 (ssl 1072)

    砝码称重 ssl 1072 题目大意: 有6种砝码,每种的个数分别为a1,a2,a3,a4,a5,a6,请问可以平出多少种重量(0除外) Description 设有1g.2g.3g.5g.10g.2 ...

  9. 【OJ8756】砝码称重V2,可达性多重背包

    砝码称重V2 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB 描述 设有1g.2g.3g.5g.10g.20g的砝码各若干枚(其总重<=100,000),要求:计 ...

最新文章

  1. idea webapp目录404问题,war包方式运行
  2. 搭建Apache Mina框架并实现Server与Client端的简单消息传递
  3. openlayers入门开发系列之热力图篇
  4. 关于 Apple Metal API 的一些想法
  5. 推荐一个Silverlight多文件(大文件)上传的开源项目(转载)
  6. 怎么修改兼容模式html,HTML5中怎么调兼容性?
  7. Access(JET-SQL)问题集锦
  8. 判断当前是什么版本浏览器
  9. 计算机 pps,计算机及其基本功能.pps
  10. keepalived 二
  11. 中国城市新分级名单(转)
  12. 分析Kvaser驱动安装到Linux系统——Kvaser安装到嵌入式Ubuntu系统的开发板IMX6Q不成功记录
  13. 朴素贝叶斯与贝叶斯信念网络
  14. 高德poi类别23个大类 261个中类 4705个小类
  15. 三季度国内光伏市场需求仍将强劲
  16. 51单片机——外部中断
  17. TMS运输管理系统介绍
  18. Python-opencv学习笔记
  19. 前清秘史――努尔哈赤
  20. matlab显示图像全黑,请教!彩色图像显示出来怎么是全黑的?

热门文章

  1. HH SaaS电商系统的销售订单毛利润模块设计
  2. php响应式布局,响应式布局之弹性布局的介绍
  3. mysql导入三个基本表_mysql 基础导入导出
  4. det曲线_平面曲线的曲率的复数表示
  5. yolov5论文_YOLOv5的妙用:学习手语,帮助听力障碍群体
  6. ios html正则表达式,ios 正则表达式去html标签
  7. excel运行没反应_Excel数据很少文件却很大,问题出在哪里呢?两种方法轻松解决...
  8. 按钮自动居中布局_CSS布局技巧
  9. 全国计算机证件照要露耳朵吗,结婚证照片要露耳朵么 结婚登记照露一只耳朵行吗...
  10. 网页编程从入门到精通 杨凡_干货 | web前端入门基础知识