砝码称重(第十二届蓝桥杯省赛第一场C++A/B/研究生组)

news/2024/9/22 8:27:51/

突然决定要参加蓝桥,已经超级久没复习C/C++的我考前还是决定打几道题捡一捡C/C++的语法和思路。

2023年蓝桥的题之后会出,因为 AcWing上还没有出可以测试的程序,也没把握说自己考场上做的就是对的。

题目

你有一架天平和 N 个砝码,这 N 个砝码重量依次是 W1W_1W1,W2W_2W2,⋅⋅⋅,WNW_NWN

请你计算一共可以称出多少种不同的正整数重量?

注意砝码可以放在天平两边。

输入格式

输入的第一行包含一个整数 N

第二行包含 N 个整数:W1W_1W1,W2W_2W2,⋅⋅⋅,WNW_NWN

输出格式

输出一个整数代表答案。

数据范围

对于 50% 的评测用例,1≤N≤15。
对于所有评测用例,1≤N≤100,N 个砝码总重不超过 10510^5105

输入样例

3
1 4 6

输出样例

10

样例解释

能称出的 10 种重量是:1、2、3、4、5、6、7、9、10、11。

1 = 1;
2 = 6 − 4 (天平一边放 6,另一边放 4);
3 = 4 − 1;
4 = 4;
5 = 6 − 1;
6 = 6;
7 = 1 + 6;
9 = 4 + 6 − 1;
10 = 4 + 6;
11 = 1 + 4 + 6。

想法

想法很朴素。这么多东西,一下子放进来算,肯定算不明白,那只能一个一个来。

一个一个来,那怎么表示第 i 个进来之前的之前的结果?

噢吼~

这不是动态规划的思想嘛。

那就设计下动态规划的表示。目测这个dp[][]应该具有三要素:

  1. 到第几个了
  2. 到这里的方案数
  3. 到这里之前有的方案是哪些

瞄一眼总重不超过 10510^5105,大胆设 dp[i][j] 表示加入第 i 个砝码时,重量 j 是不是被用了。(emmmm?好像又不是动态规划了……)

状态转移方程:dp[i][j]=max(max(dp[i-1][j], dp[i-1][j-a[i]]), dp[i-1][j+a[i]])
其中 a[i] 表示第 i 个砝码的重量

结果:sum(dp[n]) 对最后一个砝码放入后的结果求和。

注意点

  1. 重量可能为负数(例如 9 可能是这么算出来的:(3-4)+10),所以要加 offset 表示负数。
  2. 空间问题,加加减减的可能导致数组越界了,记得加个判断。
  3. 空间问题,怕数组开大了,采用滚动dp,不储存之前的结果。

代码

#include<bits/stdc++.h>
using namespace std;
int N;
// 负数 
const int offset = 100052;
// 总数
const int maxn = offset+100052;
// 砝码
int a[1005];
// 滚动dp
int dp[2][maxn];// sort 用的(实际上没什么用,复习一下罢了)
bool cmp(int a,int b){return a>=b;
}int main(){cin>>N;// 初始化为0memset(dp,0,sizeof(dp));int n = 1;while(cin>>a[n]){n++;}// 排序(没什么用其实,可以不要)sort(a+1,a+n,cmp);// 对 0 置 1dp[0][offset]=1;for(int i=1;i<n;i++){for(int j=0;j<maxn;j++){// 判断一下,怕 段错误if(j+a[i]<maxn && j-a[i]>0)dp[1][j] = max(max(dp[1-1][j], dp[1-1][j-a[i]]),dp[1-1][j+a[i]]);}// dp滚动一下for(int j=0;j<maxn;j++){dp[0][j] = dp[1][j];}
//		可以输出看看
// 		for(int j=offset+1;j<maxn;j++)
// 		    if (dp[0][j]>0)
// 		        cout<<j-offset<<"\n";
// 		cout<<"\n\n";}// 统计结果int count = 0;for(int i=offset+1;i<maxn;i++){if(dp[0][i]>0){count++;
// 			cout<<dp[n-1][i]<<"\n";}}cout<<count;return 0;
} 

AC(可能是因为题目条件比较松……)


http://www.ppmy.cn/news/40408.html

相关文章

0201服务注册源码解析-nacos2.x-微服务架构

文章目录1 搭建测试服务1.1 搭建服务1.2 启动测试2 nacos 服务注册原理2.1 客户端注册2.2 服务端注册结语1 搭建测试服务 1.1 搭建服务 我们基于springboot来搭建简单的订单和库存服务&#xff0c;通过订单服务调用库存服务,项目代码和配置在文章最后的仓库有&#xff0c;项目…

关于FTP文件传输协议说明,带你了解更详细的文件传输协议

FTP是文件传输协议的缩写。顾名思义&#xff0c;FTP用于在网络上的计算机之间传输文件。您可以使用文件传输协议在计算机帐户之间交换文件&#xff0c;在帐户和台式计算机之间传输文件或访问在线软件档案。但是请记住&#xff0c;许多文件传输协议站点已被大量使用&#xff0c;…

Android Jetpack 从使用到源码深耕【数据库注解Room 从实践到原理 】(二)

上文,我们通过一个简单的sqlite应用实例,引入了Room,知道了Room使用的便捷和好处。然后用Room的方式,重新实现了应用实例中的场景,在这个过程中,我们结合自己已有的知识体系,从使用代码入手,对Room的实现原理,进行了猜想和简单的验证。 Room实现原理,是否真如我们猜想…

Typescript - function 函数(箭头函数 / 参数类型与返回类型 / 可选参数与默认参数 / 剩余参数 / 函数重载)通俗易懂详细示例教程

前言 在 Typescript 中&#xff0c;对 JavaScript 函数进行了 “升级”&#xff0c;继承了基本功能的同时又增加了一些新用法&#xff08;使其更加严谨&#xff09;。 用一个表格&#xff0c;可以大致描绘出异同点。 TypeScriptJavaScript含有类型无类型箭头函数箭头函数&…

java程序解析jts的geometry类型并入PG数据库

场景 GIS开发&#xff0c;会有需要将jts包中的geometry类型数据存入pg&#xff08;postgis扩展后&#xff09;数据库的需求。 工程是springboot&#xff0c;mybatis作为持久层框架。 解决方案 1. pg的geometry字段对应的类型为geometry类型&#xff0c;比如&#xff1a; 2.…

面向对象三大基本特征

面向对象三大基本特征封装继承多态封装 把客观事物封装成抽象的一个类&#xff0c;并且类可以把自己的数据和方法只让可信的类或者对象来操作。 一个类就是一个封装的数据&#xff0c;以及操作这些数据的代码的逻辑实体。 在一个对象的内部&#xff0c;某些代码或者是某些数…

NTP8835(30W内置DSP双通道D类音频功放芯片)

数字功放是一种具有失真小、噪音低、动态范围大等特点的音频功率放大器&#xff1b;由工采网代理的韩国耐福旗下NTP系列专业功率放大器是ClassD功放的一个新里程碑。 NTP8835是一款高性能、高保真功率驱动集成全数字音频放大器&#xff0c;工作电压范围&#xff1a;7V&#xf…

linux上的无线网卡灯不亮

linux上的无线网卡灯不亮&#xff0c;查看了型号后&#xff0c;RTL8811CU 这个方法&#xff0c;可以说是一步到位 先克隆 git 仓库 git clone https://github.com/morrownr/8821cu-20210916.git cd 8821cu-20210916 直接运行安装脚本 ./install-driver.sh 安装完会问两个…