【题解】Luogu P2347 砝码称重

正经·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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/351015.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

matlab 获取视频图像的信息

获取视频图像的信息可以通过get函数来获取&#xff0c;如get(vid)或者get(getselectedsource(vid))。使用set函数可以设置摄像头获取的图像的一些属性值&#xff0c;也可以直接使用结构数组的“点”来赋值&#xff0c;比如&#xff0c;要持续通过摄像头获取图像&#xff0c;则可…

tomcat使用ssl_使用SSL和Spring Security保护Tomcat应用程序的安全

tomcat使用ssl如果您看过我的上一个博客&#xff0c;您会知道我列出了Spring Security可以做的十件事 。 但是&#xff0c;在开始认真使用Spring Security之前&#xff0c;您真正要做的第一件事就是确保您的Web应用使用正确的传输协议&#xff0c;在这种情况下为HTTPS –毕竟&a…

matlab delete、clf、cla、close、closereq删除对象

matlab中删除对象 删除对象 &#xff08;1&#xff09;delete&#xff1a;删除文件或对象图形 删除文件对象h的格式为&#xff1a;delete(filename)或delete filename 删除图形对象h的格式为&#xff1a;delete(h); 若要无条件删除所有的图形对象&#xff0c;则&#xff1a;set…

Linux系统调用过程分析

参考&#xff1a; 《Linux内核设计与实现》 0 摘要 linux的系统调用过程&#xff1a; 层次如下&#xff1a; 用户程序------>C库&#xff08;即API&#xff09;&#xff1a;INT 0x80 ----->system_call------->系统调用服务例程-------->内核程序 先说明一下&#…

Spring Boot和应用程序上下文层次结构

Spring Boot支持一种指定Spring应用程序上下文层次结构的简单方法。 这篇文章只是演示了此功能&#xff0c;我尚未在我从事的项目中很好地使用它。 Spring Cloud使用此功能来创建引导上下文 &#xff0c;在该上下文中&#xff0c;如果需要&#xff0c;可以从外部配置服务器加载…

drf 解析器,响应器,路由控制

解析器 作用: 根据请求头 content-type 选择对应的解析器对请求体内容进行处理。 有application/json&#xff0c;x-www-form-urlencoded&#xff0c;form-data等格式使用:局部使用:from rest_framework.parsers import JSONParser,FormParseparser_classes [JSONParser, ]全局…

matlab max与min获取矩阵最大最小值函数

1.matlab中Max的用法1&#xff08;Min类似&#xff09; Matlab中max函数在矩阵中求函数大小的实例如下: C max(A) 1&#xff09;返回一个数组各不同维中的最大元素。 2&#xff09;如果A是一个向量&#xff0c;max(A)返回A中的最大元素。 3&#xff09;如果A是一个矩阵&…

shell中exec解析

参考&#xff1a;《linux命令、编辑器与shell编程》 《unix环境高级编程》exec和source都属于bash内部命令&#xff08;builtins commands&#xff09;&#xff0c;在bash下输入man exec或man source可以查看所有的内部命令信息。 bash shell的命令分为两类&#xff1a;外部命…

今天敢用OSS放视频,明天阿里云就敢收你房子

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 请教各位大佬&#xff1a;如果网站里&#xff0c;视频多的话&#xff0c;有什么加速的办法&#xff0c;使用CDN可以嘛? 今天群友king王咨询了这个问题&#xff1a;他的客户网站在美国&#xff0c;用美国节点的服务…

matlab meshgrid

meshgrid用于从数组a和b产生网格。生成的网格矩阵A和B大小是相同的。它也可以是更高维的。 用法: [A,B]Meshgrid(a,b) 生成size(b)Xsize(a)大小的矩阵A和B。它相当于a从一行重复增加到size(b)行&#xff0c;把b转置成一列再重复增加到size(a)列。因此命令等效于&#xff1a; …

连续锁定2个不同的锁会死锁_研究死锁–第5部分:使用显式锁定

连续锁定2个不同的锁会死锁在我的上一个博客中&#xff0c;我研究了使用Java的传统synchronized关键字和锁排序来修复破碎的&#xff0c;死锁的余额转移示例代码。 但是&#xff0c;有另一种方法称为显式锁定。 在这里&#xff0c;将锁定机制称为显式而非隐式的想法是&#xf…

fork source exec区别差异

fork 使用 fork 方式运行 script 时, 就是让 shell(parent process) 产生一个 child process 去执行该 script, 当 child process 结束后, 会返回 parent process, 但 parent process 的环境是不会因 child process 的改变而改变的. source 使用 source 方式运行 scrip…

LOJ2980 THUSC2017大魔法师(线段树+矩阵乘法)

线段树每个节点维护(A,B,C,len)向量&#xff0c;操作即是将其乘上一个矩阵。 #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long lo…

在ECR上推送Spring Boot Docker映像

在先前的博客中&#xff0c;我们将Spring Boot应用程序与EC2集成在一起。 它是您可以在Amazon Web Services上进行的最原始的部署形式之一。 在本教程中&#xff0c;我们将使用我们的应用程序创建一个docker映像&#xff0c;该映像将存储到Amazon EC2容器注册表中 。 您需要安…

Linux信号处理机制

在Linux中&#xff0c;信号是进程间通讯的一种方式&#xff0c;它采用的是异步机制。当信号发送到某个进程中时&#xff0c;操作系统会中断该进程的正常流程&#xff0c;并进入相应的信号处理函数执行操作&#xff0c;完成后再回到中断的地方继续执行。 需要说明的是&#xff0…

pyspider爬虫框架

特点&#xff1a; 去重处理&#xff0c;结果监控&#xff0c;多进程处理&#xff0c;pyquery提取&#xff0c;错误重试&#xff0c;webUI管理&#xff0c;代码简洁&#xff0c;JS渲染 安装&#xff1a; anaconda里边没搜到pyspider&#xff0c;所以手动安装 查看pyspider的命令…

matlab subplot同时显示多幅图像

subplot是MATLAB中的函数。 使用方法&#xff1a;subplot&#xff08;m,n,p&#xff09;或者subplot&#xff08;m n p&#xff09;。 subplot是将多个图画到一个平面上的工具。其中&#xff0c;m表示是图排成m行&#xff0c;n表示图排成n列&#xff0c;也就是整个figure中有n个…

matlab var求方差

对二维数组a b1 var(a); % 按默认来求 b2 var(a, 0); % 默认的公式&#xff08;用N-1&#xff09; c1 var(a, 1); % 另外的公式&#xff08;用N&#xff09; d1 var(a, 0, 1); % 对每列操作&#xff08;用N-1&#xff09; d2 var(a, 0, 2); % 对每行操作&#xff08;…

1. git基础

1. 安装git sudo apt-get install git 2. 注册 git config --global user.name "Your Name" git config --global user.email "emailexample.com" 3. 创建版本库 mkdir learngit cd learngitgit init ##将这个目录初始化成…