leetcode 第133场双周赛 100333.统计逆序对的数目【计数dp/滚动数组/前缀和优化】

在这里插入图片描述
分析:
先考虑如下问题。

求长度为n,逆序对为m的排列数量。

可以考虑dpdp[i][j]定义为长度为i,逆序对为j的排列数量。

dp[1][0] = 1;
//枚举排列长度,或者认为枚举当前需要插到长度为i-1的排列中的数字
for(int i = 1; i <= n; ++i)  
{for(int j = 0; j <= i * (i + 1) / 2; ++j){//枚举当前数字插到的位置,一共i个位置,分别可能使逆序对增加0~i-1个for(int k = 0; k < i; ++k){if(j >= k){dp[i][j] += dp[i - 1][j - k];}}}
}

在懂了上述dp之后,再来考虑本题。主要有两个问题。

  • 另外考虑,如果dp[i][j]是否依旧可以这样求,因为上述问题中对于长度为i的排列,前i-1个数字确定的,i一定是最大的,我们只需要考虑它放在哪个位置即可。
  • 如何同时满足requirements[i][endi] = cntirequirements[j][endj] = cntj,其中i!=j

对于第一点,肯定是可以这样求的,一方面我们不需要关心前i-1个数字是什么,只需要认为我们枚举的第i个数字是这i个数字中最大的(类似上述思路)或者是最小的(与最大的等效并且更加方便理解上述dp的最内层循环)即可,另一方面我们看到至少有一个i满足endi == n - 1

对于第二点,我们只需要在dp的过程中适当修改。若 ∃ e n d j = = i \exists end_j == i endj==i,则正常求 d p [ i ] [ c n t j ] dp[i][cnt_j] dp[i][cntj]的值,而 d p [ i ] [ k ] = 0 , k ≠ c n t j dp[i][k]=0,k\ne cnt_j dp[i][k]=0,k=cntj

AC代码

class Solution {
public:int numberOfPermutations(int n, vector<vector<int>>& requirements) {const int mod = 1e9 + 7;vector<int> vt(305, -1);for(auto x: requirements) vt[x[0] + 1] = x[1];vector<vector<int>> dp(305, vector<int>(405, 0));dp[0][0] = 1;for (int i = 1; i <= n; ++i) {if (vt[i] != -1) {int j = vt[i];for (int k = 0; k < i; ++k) if (j >= k) dp[i][j] = (dp[i][j] + dp[i - 1][j - k]) % mod;continue;}for (int j = 0; j <= min(400, (1 + i) * i / 2); ++j) {for (int k = 0; k < i; ++k) {if (j >= k) dp[i][j] = (dp[i][j] + dp[i - 1][j - k]) % mod;}}}return dp[n][vt[n]];}
};
//dp数组定义为vector,如果定义为数组,一定记得先memset 0
//(dp[i][j] += dp[i - 1][j - k]) % mod不等价于dp[i][j] = (dp[i][j] + dp[i - 1][j - k]) % mod;
//(dp[i][j] += dp[i - 1][j - k]) % mod,模完之后值未赋给任何数。

上述代码已经可以AC,但是可以进一步优化

  • dp[i][j]的递推过程中,只用到了dp[i-1][j-k],故可以通过滚动数组优化空间。
  • 对于最内层枚举k的循环,我们发现递推公式等价于 d p [ i ] [ j ] = ∑ k = j − ( i − 1 ) j d p [ i − 1 ] [ k ] dp[i][j] = \sum_{k=j-(i-1)}^{j} dp[i-1][k] dp[i][j]=k=j(i1)jdp[i1][k],即是dp[i-1]数组的一个前缀和,故可以预处理出前缀和,使得dp[i][j]实现O(1)递推,优化为两层循环。

优化后的代码:

class Solution {
public:int numberOfPermutations(int n, vector<vector<int>>& requirements) {const int mod = 1e9 + 7;vector<int> vt(305, -1);for(auto x: requirements) vt[x[0] + 1] = x[1];vector<int> dp(405, 0);vector<int> sum(405, 0);dp[0] = 1;for (int i = 1; i <= n; ++i) {sum[0] = dp[0];for(int j = 1; j <= min(400, (1 + i) * i / 2); ++j) sum[j] = (sum[j - 1] + dp[j]) % mod;if (vt[i] != -1) {for(int j = 0; j <= min(400, (1 + i) * i / 2); ++j) dp[j] = 0;int j = vt[i];if(j < i) dp[j] = sum[j];else dp[j] = (sum[j] - sum[j - i] + mod) % mod;continue;}for (int j = 0; j <= min(400, (1 + i) * i / 2); ++j) {if(j < i) dp[j] = sum[j];else dp[j] = (sum[j] - sum[j - i] + mod) % mod;}}return dp[vt[n]];}
};

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

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

相关文章

OpenAI封杀不支持地区API:违规封号,7月9日生效

OpenAI 在检测用户使用其 API 的地区后&#xff0c;提示所有不支持位置的用户 昨晚&#xff0c;很多大模型应用的开发者、程序员都收到了 OpenAI 的警告信&#xff0c;心里一惊。 OpenAI 在检测用户使用其 API 的地区后&#xff0c;提示所有不支持位置的用户&#xff1a;即将封…

冒泡排序、选择排序、插入排序~java版

1、冒泡排序&#xff08;Bubble Sort&#xff09; 冒泡排序的基本思想是多次遍历待排序序列&#xff0c;每次遍历时两两比较相邻元素&#xff0c;如果顺序不对则交换&#xff0c;直到整个序列有序为止。 public class BubbleSort {public static void bubbleSort(int[] arr) …

图书管理系统(附源码)

前言&#xff1a;前面一起和小伙伴们学习了较为完整的Java语法体系&#xff0c;那么本篇将运用这些知识连串在一起实现图书管理系统。 目录 一、总体设计 二、书籍与书架 书籍&#xff08;Book&#xff09; 书架&#xff08;Booklist&#xff09; 三、对图书的相关操作 I…

已解决问题 | 该扩展程序未列在 Chrome 网上应用店中,并可能是在您不知情的情况下添加的

在Chrome浏览器中&#xff0c;如果你看到“该扩展程序未列在 Chrome 网上应用店中&#xff0c;并可能是在您不知情的情况下添加的”这样的提示&#xff0c;通常是因为该扩展程序没有通过Chrome网上应用店进行安装。以下是解决这个问题的步骤&#xff1a; 解决办法&#xff1a;…

Spring Boot整合Redis缓存的最佳实践

Spring Boot整合Redis缓存的最佳实践 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在现代应用开发中&#xff0c;缓存是提升系统性能和响应速度的关键技术之…

kali/ubuntu安装vulhub

无须更换源&#xff0c;安装docker-compose apt install docker.io docker -vdocker-compose #提示没有&#xff0c;输入y安装mkdir -p /etc/docker vi /etc/docker/daemon.json #更换dockerhub国内源┌──(root㉿kali)-[/home/kali/vulhub-master/tomcat/CVE-2017-12615] …

【VScode】常规插件安装

以下是VScode常规插件安装&#xff1a; C/C C/C extension pack C/C themes Draw.io integration highlight 以上插件安装完毕后&#xff0c;可实现 字体高亮&#xff0c;自动补齐&#xff0c;函数跳转&#xff0c;主题切换&#xff0c;图表生成等常用功能。

中介子方程三十七

XXFXXuXXWXXuXXdXXrXXαXXuXpXXKXηXiXXnXXyXηXyXXnXXiXηXKXXpXuXXαXXrXXdXXuXWXπXXWXeXyXeXbXπXpXXNXXqXeXXrXXαXXuXpXXKXηXiXXnXXyXηXyXXnXXiXηXKXXpXuXXαXXrXXeXqXXNXXpXπXbXeXyXeXWXXπXWXuXXdXXrXXαXXuXpXXKXηXiXXnXXyXηXyXXnXXiXηXKXXpXuXXαXXrXXdXXuXXW…

【TensorFlow深度学习】对比学习的核心:实例与上下文的对抗

对比学习的核心&#xff1a;实例与上下文的对抗 对比学习概述实例与上下文的对抗&#xff1a;核心机制实战代码示例&#xff1a;使用PyTorch实现SimCLR结语 在深度学习的浩瀚星海中&#xff0c;对比学习作为自我监督学习的一个分支&#xff0c;正以破竹之势引领着无标注数据利用…

dledger原理源码分析系列(三)-选主

简介 dledger是openmessaging的一个组件&#xff0c; raft算法实现&#xff0c;用于分布式日志&#xff0c;本系列分析dledger如何实现raft概念&#xff0c;以及dledger在rocketmq的应用 本系列使用dledger v0.40 本文分析dledger的选主 关键词 Raft Openmessaging 心跳/选…

SpringMVC中的异常处理器

文章目录 12异常处理器12.1基于配置的异常处理HandlerExceptionResolver接口直接在springmvc中声明使用 12.2基于注解的异常处理需要书写异常的配置类 12异常处理器 12.1基于配置的异常处理 HandlerExceptionResolver接口 接口实现类&#xff1a; DefaultHandlerExceptionR…

Linux安装redis教程(超级详细,新手必看)

环境&#xff1a; Centos 7.9 一、安装准备工作 1.配置gcc 安装redis前需要配置gcc&#xff1a; yum install gcc如果配置gcc出现依赖包问题&#xff0c;可以到主页查看帖子解决&#xff1a;https://blog.csdn.net/m0_59117906/article/details/134451622?spm1001.2014.300…

这四款软件很好用,可以提升工作、学习效率

TableConvert TableConvert是一个基于Web的在线表格转换工具&#xff0c;能够将多种格式的表格数据进行快速转换。它支持将Excel、URL、HTML、JSON、CSV等格式转换为Markdown表、CSV/TSV、XML、YAML、插入SQL、HTML、Excel和LaTeX等格式。用户只需将表格数据粘贴到编辑器&#…

设置HTML元素的背景颜色

设置HTML元素的背景颜色 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;在本文中&#xff0c;我们将探讨如何使用HTML和CSS来设置HTML元素的背景颜色。背景颜色…

本教程将指导如何通过 Vue 组件和后端 API 交互

本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》 公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯 山峯 转载说明:务必注明来源(注明:作者:王文峰…

常用TELNET命令及其应用

常用TELNET命令及其应用 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; TELNET是一种基于文本协议的网络协议&#xff0c;主要用于远程登录到网络设备和服务器…

计算机视觉全系列实战教程 (十五):使用opencv对视频进行基本处理

视频处理基本介绍 1、基本概述(1)opencv中视频处理的两个基础类(2)视频的属性&#xff1a;获取属性和设置属性 2、VideoCapture的介绍(1)Why( VideoCapture类的作用)(2)How( 如何使用VideoCapture)A.播放视频文件函数B.播放视频文件并实现暂停和继续 3、VideoWriter类的介绍(1)…

CJSON库

目录 一、介绍 1、JSON是什么 2、为什么使用CJSON 3、JSON格式 二、使用CJSON构造JSON 1、创建对象 2、添加字段 3、转换格式 4、释放对象 三、使用CJSON解析JSON 1、解析数据 2、 获取字段 3、释放对象 一、介绍 1、JSON是什么 JSON是什么呢&#xff1f;JSON全称…

折半查找详解

一&#xff1a;折半查找概念 折半查找&#xff08;也称为二分查找&#xff09;是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始&#xff0c;如果中间元素正好是目标值&#xff0c;则搜索过程结束&#xff1b;如果目标值大于或小于中间元素&#x…

OceanBase 4.2.1 离线安装

OceanBase 4.2.1 离线安装 4.2 版本的OceanBase支持一键安装&#xff0c;所以在线版本的安装简单了很多&#xff0c;但在无法连接网络的情况下安装就只能手动离线安装。 注&#xff1a;如下安装过程都是在同一台机器上面进行&#xff0c;也就是只有一个节点&#xff0c;多个节…