AcWing 5386. 进水出水问题【线性dp+差值dp】

原题链接:https://www.acwing.com/problem/content/5389/

某泳池装有 n 个水管,编号 1∼n。

每个水管都是既可用于进水,也可用于出水。

其中,第 i 个水管工作时的单位时间进水或出水量为 ai。

我们希望泳池保持水循环的同时,还能够保持水位不变。

为此,我们需要制定一种水管工作方案。

具体要求为:

  1. 选择若干个(至少一个)连续编号的水管作为工作水管(未选择的水管不工作)。
  2. 每个工作水管,要么用于进水,要么用于出水。
  3. 所有安排完毕以后,所有用于进水的工作水管的进水量之和应当等于所有用于出水的工作水管的出水量之和。

请你计算,一共可以制定出多少种不同的水管工作方案。

注意,(1 号水管进水、2 号水管出水)和(1 号水管出水、2 号水管进水)应当视为两种不同的方案,虽然它们用到的工作水管相同,但是水管的具体安排(进水或出水)不同。

输入格式

第一行包含整数 n。

第二行包含 n 个整数 a1,a2,…,an。

输出格式

一个整数,表示可以制定出的不同方案的总数量对 1e9+7 取模后的结果。

数据范围

前 3 个测试点满足 1≤n≤10。
所有测试点满足 1≤n≤1000,1≤ai≤1000,ai<=10000(1<=i<=n)

输入样例:
4
1 1 1 1
输出样例:
12
解题思路:

首先看到这种求方案数,又有方案数可能很大需要取模,那么这个题目十有八九就是可以推出数学公式或者就是dp,,但是我没有发现可以推出什么公式,但是从题目可以看到俩个操作,对于选定工作的水管,要么用于进水,要么用于出水,这很像线性dp的常规操作,我首先想到的就是首先枚举所有区间然后对于每个区间进行线性dp,但是这个方法时间复杂度太高了,根本过不了, 而且也找不到很好的优化方式,看到n=1000,如果先枚举所有区间再dp显然是不现实的,我们可以看看有没有什么好的状态定义方式使得不需要暴力枚举所有区间,而是可以直接设置状态进行dp呢,我们可以发现题目要求选择的一段连续工作水管的进水量和出水量需要相同,涉及到俩个变量,进水量之和最多是0-10000,出水量之和最多是0-10000,同时要使得进水量之和和出水量之和相同就是要使得进水量和出水量的差值为0,这个时候我们看到了差值这个词,那么我们可以尝试使用差值设计状态,以前貌似没见过这种差值状态设计,所以这次确实没有想出来这样设计状态。

状态定义:

定义:f[i][j]表示以i结尾并且进水量和出水量的差值为j的所有方案

初始状态:

正常情况下,我们会设f[0][0]=1,但是这个题目不能这样设初始状态,如果这样设初始状态,当i==1时,会导致(1)(3)或者(2)(4)出现重复计算情况,所以我们不这样设初始状态,出现这种情况是因为当i==1时,第(3)种情况虽然定义的是前面还有管子,但是在当前是第一根管子时,前面根本就没有管子了,导致此时第(3)变为了和(1)一样,相当于这种情况被计算了俩次,导致了重复计算。我们将所有的f[i][a[i]]和f[i][-a[i]]初始值定为1即可,因为工作的水管必须是连续的,所以状态定义状态转移时不仅需要考虑当前位置进水或者出水,而且还需要考虑当前位置前面还有没有工作的水管,所以这就是为什么我们的初始状态不能按照常规方式去设的原因,也是常规做法状态转移只有俩种情况,但是这里有四种状态转移情况的原因。

状态转移:

(1)当前位置管子设为进水,并且前面没有工作管子了

f[i][a[i]]++;

(2)当前位置管子设为出水,并且前面没有工作管子了

f[i][-a[i]]++;

(3)当前位置管子设为进水,并且前面还有工作管子

f[i][j]=(f[i][j]+f[i-1][j-a[i]])

(4)当前位置管子设为出水,并且前面还有工作管子

f[i][j]=(f[i][j]+f[i-1][j+a[i]]);

最终答案

答案是所有的f[i][0]的和

注意由于我们定义的是差值,所以我们这个状态转移方程会出现负数下标,我们需要对状态转移方程做一个等价偏移,a数组所有数的和最大是10000,所以出现的负数最小值为-10000,我们设置偏移值为10000即可。

时间复杂度:第一维枚举水管,时间为O(n),第二位枚举差值时间为O(20000),最终时间为1000*20000,大概是2e7,这个时间复杂度是可以过的。

空间复杂度:2e7/1e6*8=160,大概是160M,题目给了256M,所以空间是足够的,如果我们将f定义为int类型,那么可以将空间降低到80M,这个题目给了256M,所以f数组定义为long long 类型也是可以的。

cpp代码如下

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>using namespace std;
typedef long long LL;const int N=1010,M=20010,mod=1e9+7,B=10000;  //B为偏移值int n;
int a[N];
LL f[N][M];  //f[i][j]表示以i结尾并且进水值和出水值之差为j的所有方案
int main()
{cin>>n;for(int i=1;i<=n;i++)scanf("%d",&a[i]);int res=0;for(int i=1;i<=n;i++){   //开始的范围是-10000~10000,偏移之后就是0~20000for(int j=0;j<=20000;j++){//当前位置进水if(j-a[i]>=0)f[i][j]=(f[i][j]+f[i-1][j-a[i]])%mod;//当前位置出水if(j+a[i]<=20000)f[i][j]=(f[i][j]+f[i-1][j+a[i]])%mod;}//设置f[i][a[i]]和f[i][-a[i]]的初始值为1f[i][B+a[i]]++,f[i][B-a[i]]++;res=(res+f[i][B])%mod;  //对于所有的f[i][0]求和就是答案,偏移之后是f[i][B]}cout<<res<<endl;return 0;
}

总结:之前貌似没有遇到过这种状态设计方式,所以当时没想出来,这次学会了,吸取教训,下次还遇到类似的希望能很快就想出来状态设计吧。 

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

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

相关文章

【机器学习300问】7、怎么进行机器学习?机器学习的基本流程是什么?

一、写在前面 也许你和我一样&#xff0c;在刚开始学习机器学习的基本知识的时候&#xff0c;学到了很多的零碎知识点&#xff0c;无法穿成线织成网&#xff0c;本文是机器学习中提纲挈领的一环&#xff0c;将和你一起将今后所有的知识点都捕捉在这张网中。 当你在问“…

仿stackoverflow名片与b站名片实现(HTML、CSS)

目录 前言一、仿stackoverflow名片HTMLCSS 二、仿b站名片HTMLCSS 素材 前言 学习自ACwing - Web应用课 一、仿stackoverflow名片 HTML <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport&…

BDD(Behavior-Driven Development)行为驱动开发介绍

为什么需要BDD&#xff1f; “开发软件系统最困难的部分就是准确说明开发什么” (“The hardest single part of building a software system is deciding precisely what to build” — No Silver Bullet, Fred Brooks) 。 看一下下面的开发场景&#xff1a; 场景一&#xf…

生成随机id

在Node.js中&#xff0c;你可以使用uuid模块来生成随机的ID。uuid模块提供了多种生成唯一标识符的方法&#xff0c;包括基于时间戳、随机数等不同的算法。 以下是一个简单的示例&#xff0c;演示如何在Node.js中使用uuid模块生成随机ID&#xff1a; 首先&#xff0c;你需 np…

基于TCP的全双工网络编程实践

首先我们先了解一下什么是全双工通信&#xff1f; 全双工数据通信允许数据同时在两个方向上传输&#xff0c;因此&#xff0c;全双工通信相当于是两个单工通信方式的结合&#xff0c;它要求发送设备和接收设备都有独立的接收和发送能力。 TCP服务端代码&#xff1a; #includ…

M-VAE

Word2Vec c(y) 辅助信息 作者未提供代码

音频和视频基础知识

声音 什么是声音&#xff1a; 声音是由物体振动产生的&#xff0c;物体发生振动&#xff0c;对周围的空气产生挤压&#xff0c;从而产生声音。声音是一种压力波&#xff0c;使周围的空气产生疏密变化&#xff0c;形成疏密相间的纵波&#xff0c;由此产生了声波。 声波三要素&…

小程序跳转安卓会跳转两次 iOS不会的解决方案

原因&#xff1a;元素点击事件在子元素上有绑定&#xff0c;父元素上也有绑定会形成冒泡事件&#xff1b; 原生小程序&#xff1a; bind:tap&#xff1a;会冒泡&#xff1b; <view bind:tap"gotoDetail"><image :src"{{ item2.img }}" mode&qu…

HUAWEI华为MateStation S台式机电脑12代PUC-H7621N,H5621N原装出厂Windows11.22H2系统

链接&#xff1a;https://pan.baidu.com/s/1QtjLyGTwMZgYiBO5bUVPYg?pwd8mx0 提取码&#xff1a;8mx0 原厂WIN11系统自带所有驱动、出厂主题壁纸、系统属性专属联机支持标志、Office办公软件、华为电脑管家等预装程序 文件格式&#xff1a;esd/wim/swm 安装方式&#xf…

dbeaver连接人大金仓报错 can‘t load driver class ‘com.kingbase8.Driver;‘

dbeaver可以连接很多数据库&#xff0c;设置dbeaver连接人大金仓&#xff0c;下载安装完成后&#xff0c;需要自行配置人大金仓的驱动&#xff0c;否则无法连接数据库。 一、dbeaver 下载 dbeaver 下载地址&#xff1a;https://dbeaver.io/download/ 二、查找人大金仓驱动 首…

[含完整代码]Linux使用.sh脚本自动部署(启动|停止|状态|日志)项目[超详细]

前言&#xff1a; 个人博客&#xff1a;www.wdcdbd.com 我们在linux部署.jar项目时&#xff0c;都需要通过java -jar的形式来部署&#xff0c;每次都要手动停止&#xff0c;部署&#xff0c;这样用起来会很麻烦。所以&#xff0c;这篇文章就是自己通过.sh脚本一键启动&#xf…

XCTF:hello_pwn[WriteUP]

使用checksec查看ELF文件信息 checksec 4f2f44c9471d4dc2b59768779e378282 这里只需要注意两个重点&#xff1a; Arch&#xff1a;64bit的文件&#xff0c;后面写exp的重点 Stack&#xff1a;No canary found 没有栈溢出保护 使用IDA对ELF文件进行反汇编 双击左侧的函数栏…

库函数点亮Led

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 例如&#xff1a;…

陶瓷碗口缺口检测-图像分割

图像分割 由于对碗口进行缺口检测&#xff0c;因此只需要碗口的边界信息。得到陶瓷碗区域填充后的图像&#xff0c;对图像进行边缘检测。这是属于图像分割中的内容&#xff0c;在图像的边缘中&#xff0c;可以利用导数算子对数字图像求差分&#xff0c;将边缘提取出来。 本案…

【算法刷题】总结规律 算法题目第2讲 [234] 回文链表,因为深浅拷贝引出的bug

配合b站视频讲解食用更佳:https://www.bilibili.com/video/BV1vW4y1P7V7 核心提示&#xff1a;好几道题是处理有序数组的&#xff01; 适合人群&#xff1a;考研/复试/面试 解决痛点&#xff1a;1. 刷了就忘 2.换一道相似的题就不会 学完后会输出&#xff1a;对每类题目的框架…

test-04-test case generate 测试用例生成 tcases A model-based test case generator

拓展阅读 junit5 系列 基于 junit5 实现 junitperf 源码分析 Auto generate mock data for java test.(便于 Java 测试自动生成对象信息) Junit performance rely on junit5 and jdk8.(java 性能测试框架。性能测试。压测。测试报告生成。) 自动生成测试用例 Tcases&#xf…

查看lucene和elasticsearch的版本对应关系

一、Maven仓库官网&#xff1a; https://mvnrepository.com/ 二、搜索elasticsearch&#xff0c;然后点击Server或者elasticsearch进入。 三、点击相应的版本号进入。 四、查看对应的lucene版本。 END

spring cloud feign介绍以及和dubbo对比

什么是feign 在微服务架构中&#xff0c;Feign 是一个声明式的 web 服务客户端&#xff0c;它使得编写 web 服务客户端变得更加容易。Feign 旨在帮助开发者轻松地调用远程服务。它是由 Netflix 开发的一部分 Spring Cloud Netflix 微服务套件。Feign 通过提供一个简洁的模板化…

SwiftUI CoreData Picker

开发多账本功能 CoreData 与 Picker 的使用 上代码&#xff1a; // // TestZhangBenPicker.swift // pandabill // // Created by 朱洪苇 on 2024/1/14. //import SwiftUIstruct TestZhangBenPicker: View {FetchRequest(sortDescriptors: [SortDescriptor(\.cc_at)],anima…

JavaWeb,JavaScript的学习(上)

由于是JavaWeb的学习&#xff0c;是建立在已经学过Java的基础上。所以很多地方与Java做对比&#xff0c;然后没有把多余的内容详细写出来。 JS的引入方式 内嵌式 在head中通过一对script标签定义脚本代码 例&#xff1a; <!DOCTYPE html> <html lang"en&quo…