南大算法设计与分析课程OJ答案代码(2)最大子序列和问题、所有的逆序对
问题 A: 最大子序列和问题
时间限制: 1 Sec 内存限制: 4 MB
提交: 184 解决: 66
提交 状态 算法问答
题目描述
给定一整数序列 a1, a2, …, an,求 a1~an 的一个子序列 ai~aj,使得从 ai 到 aj 的和最大。
只需要求出最大子序列的和,而不需要求出最大的那个序列。
输入
输出
样例输入-2 11 -4 13 -5 -2 |
样例输出20 |
提示
利用分治的思想可以有 O(n*logn) 的算法。
也有聪明的算法,它的复杂度是 O(n) 的。
另请注意:输入多少个数是未知的。请思考如何处理。
答案看这里
问题 B: 所有的逆序对
时间限制: 2 Sec 内存限制: 5 MB
提交: 289 解决: 49
提交 状态 算法问答
题目描述
给出一个字符串数组,如果(按照字典序)一个大的字符串在比它小的字符串前面我们称这两个字符串组成一个“逆序对”。你需要找到所有的逆序对的个数。
输入
第一行是数组大小,第二行是以空格分隔的字符串数组.
注:预先知道每个字符串的长度都是 10.
输出
所有的逆序对个数. 这次需要大家先输出一个字符串,它是“我已阅读关于抄袭的说明”的汉语拼音.输出此行的提交我们将认为已经完全阅读并了解了“关于抄袭的说明”公告.
注意:结果比较大,请用 long 类型保存.
样例输入3 |
样例输出wo yi yue du guan yu chao xi de shuo ming |
提示
不要使用蛮力算法
答案
暴力解法,会超时
long long a(vector<string>& v, int pos1, int pos2) {
long long w = ;
for (int i = pos1; i <= pos2; ++i) {
for (int j = i + ; j <= pos2; ++j) {
if (v[i] > v[j])
++w;
}
}
return w;
}
bf
归并排序的思想,只需要在归并排序的基础之上加上一个统计量,和一行代码,但是下面的做法会超出内存限制
void merge(vector<string>& v, int pos1, int mid, int pos2, long long& nums) {
//从0开始的数组,如果两个位置分别为p1和p2,其中p1<p2,则p1到p2距离的元素有p2-p1+1个
vector<string> n1 (v.begin()+pos1,v.begin()+mid+);
vector<string> n2 (v.begin()+mid+,v.begin()+pos2+);
n1.emplace_back("zzzzzzzzzzzzzzzzzzzz");
n2.emplace_back("zzzzzzzzzzzzzzzzzzzz");
int n1_pos = ;
int n2_pos = ;
for (int i = pos1; i <= pos2;++i) {
if (n1[n1_pos] <= n2[n2_pos]) {
v[i] = n1[n1_pos];
++n1_pos;
}else{
//在这加上统计量
nums += n1.size() - n1_pos-;
v[i] = n2[n2_pos];
++n2_pos;
}
}
}
void mergesort(vector<string>& v, int pos1, int pos2, long long& nums) {
if (pos1 < pos2) {
int mid = (pos1 + pos2) / ;
mergesort(v,pos1,mid,nums);
mergesort(v,mid+,pos2,nums);
merge(v,pos1,mid,pos2,nums);
}
}
//这是测试用例
int main()
{
int nums = ;
cin >> nums;
string temp;
vector<string> v(nums,"");
for (int i = ; i < nums; ++i) {
cin >> temp;
v[i] = temp;
}
vector<string> v = { "aaaaaaaaaa", "cccccccccc", "bbbbbbbbbb" };
long long result = ;
mergesort(v, , v.size() - , result);
cout << "wo yi yue du guan yu chao xi de shuo ming" << endl;
cout << result << endl;
//system("pause");
return ;
}
归并解法
经大佬提醒,不在递归时分配vector,而是在开始递归之前申请一个help的vector用来帮助归并排序,这样可以减小内存使用,但是上面使用哨兵的方法就不能用了,代码稍微复杂了一些,但任然是归并排序加上一行统计代码。
void merge(vector<string>& v, int pos1, int mid, int pos2, long long& nums, vector<string>& help) {
//从0开始的数组,如果两个位置分别为p1和p2,其中p1<p2,则p1到p2距离的元素有p2-p1+1个
for (int i = pos1; i <= pos2; ++i)
help[i] = v[i];
int n1_pos = pos1;
int n2_pos = mid+;
for (int i = pos1; i <= pos2;++i) {
//当一个数组已经遍历完成时
if (n1_pos == mid + ) {
while (n2_pos != pos2 + ) {
v[i++] = help[n2_pos++];
}
break;
}
if (n2_pos == pos2 + ) {
while (n1_pos != mid + ) {
v[i++] = help[n1_pos++];
}
break;
}
//其他情况
if (help[n1_pos] <= help[n2_pos]) {
v[i] = help[n1_pos];
++n1_pos;
}else{
//在这加上统计量
nums += mid-n1_pos+;
v[i] = help[n2_pos];
++n2_pos;
}
}
}
void mergesort(vector<string>& v, int pos1, int pos2, long long& nums,vector<string>& help) {
if (pos1 < pos2) {
int mid = (pos1 + pos2) / ;
mergesort(v,pos1,mid,nums,help);
mergesort(v,mid+,pos2,nums,help);
merge(v,pos1,mid,pos2,nums,help);
}
}
//这是测试用例
int main()
{
int nums = ;
cin >> nums;
string temp;
vector<string> v(nums,"");
for (int i = ; i < nums; ++i) {
cin >> temp;
v[i] = temp;
}
//vector<string> v = { "4","3","2","1" };
vector<string> help(v.size()," ");
long long result = ;
mergesort(v, , v.size() - , result,help);
cout << "wo yi yue du guan yu chao xi de shuo ming" << endl;
cout << result << endl;
system("pause");
return ;
}
归并排序内存优化
南大算法设计与分析课程OJ答案代码(2)最大子序列和问题、所有的逆序对的更多相关文章
- 南大算法设计与分析课程OJ答案代码(3)
问题 A: 动态中位数问题 时间限制: 1 Sec 内存限制: 8 MB提交: 866 解决: 102提交 状态 算法问答 题目描述 输入一组整数a1, a2, …, an ,每输入一个整数,输出 ...
- 南大算法设计与分析课程OJ答案代码(5)--割点与桥和任务调度问题
问题 A: 割点与桥 时间限制: 1 Sec 内存限制: 5 MB提交: 475 解决: 34提交 状态 算法问答 题目描述 给出一个无向连通图,找到所有的割点和桥 输入 第一行:点的个数,如果点 ...
- 南大算法设计与分析课程OJ答案代码(4)--变位词、三数之和
问题 A: 变位词 时间限制: 2 Sec 内存限制: 10 MB提交: 322 解决: 59提交 状态 算法问答 题目描述 请大家在做oj题之前,仔细阅读关于抄袭的说明http://www.bi ...
- 南大算法设计与分析课程OJ答案代码(1)中位数附近2k+1个数、任意两数之和是否等于给定数
问题1 用来测试的,就不说了 问题2:中位数附近2k+1个数 给出一串整型数 a1,a2,...,an 以及一个较小的常数 k,找出这串数的中位数 m 和最接近 m 的小于等于 m 的 k 个数,以及 ...
- 南大算法设计与分析课程复习笔记(1) L1 - Model of computation
一.计算模型 1.1 定义: 我们在思考和处理算法的时候是机器无关.实现语言无关的.所有的算法运行在一种“抽象的机器”之上,这就是计算模型. 1.2 种类 图灵机是最有名的计算模型,本课使用更简单更合 ...
- 南大算法设计与分析课程复习笔记(4)L4 - QuickSort
一.快速排序 算法导论上关于快速排序有两种写法 第一种,从头到尾遍历,不断将小于基准元素的项移到前面.代码很简介,只需要维护一个交换位置,表示小于基准元素的末尾位置加一 我们看算法导论上的一个例子: ...
- 南大算法设计与分析课程复习笔记(3)L3 - Recursion
一.递归方程 按照分治的思想,可以将一个递归的复杂度写成递归方程 一.解递归方程--猜然后证明 该方法又称为代入法,步骤如下: 1.猜解的形式 2.数学归纳法证明正确 例子: 我们假设有如下递归式: ...
- 南大算法设计与分析课程复习笔记(2)L2 - Asymptotics
一.几种比较复杂度的符号 数据结构有描述,相关严格数学定义也不想说了,就这么过了吧. 二.最大子数组的几种解决方法 从最复杂的暴力解法过渡到最简单的动态规划 解析和代码见这里:http://www.c ...
- 算法设计与分析 - AC 题目 - 第 5 弹(重复第 2 弹)
PTA-算法设计与分析-AC原题 - 最大子列和问题 (20分) 给定K个整数组成的序列{ N1, N2, ..., NK },“连续子列”被定义为{ Ni, Ni+, ..., Nj },其中 ≤i ...
随机推荐
- parrot os 更新到3.7后无法上网(DNS暂时无法解析)
parrot os 更新到最新后可能ping的通IP,ping不通域名,是DNS解析出问题了 修改/etc/resolv.conf sudo rm /etc/resolv.conf sudo vi / ...
- php中ob_get_contents、curl_multi_init、curl_init多线程下载远程图片并保存记录
php中三种方式测试图片下载效率 原文共24张不同图,每张大小在500K以上 使用时注意调整传入数组格式以及需要下载时保存地址的路径格式等 这三种方式无需额外安装扩展,方便快捷易操作[虽然效率看结果没 ...
- Shell条件测试和流程控制-4
- Android中实现gif动画
一.需求 Android本身没有提供直接显示gif动画的相关控件,因此需要自定义GifImageView类来实现gif的播放,主要是使用的Movie类来解决的. 二.自定义GifImageView p ...
- 133. leetcode-Clone Graph
拷贝图,可以一边遍历一边拷贝 DFS class Solution { public: Node* cloneGraph(Node* node) { unordered_map<int, Nod ...
- CLion之C++框架篇-优化框架,引入boost(三)
背景 结合上一篇CLion之C++框架篇-优化框架,单元测试(二),继续进行框架优化!这一版优化引入一个我们日常经常使用的操作库Boost,估算使用频率在70%以上! Boost的优势在哪 ...
- IEDA的程序调试debug
以前只是浅层面的使用dubug来查看程序运行顺序,排查一些异常的原因, 今天由于要学习一些源码,所以系统的记录一下(借鉴网上资料总结而来) 主要涉及到的功能区为如下: A::重启项目 快捷键 Ctrl ...
- [Swift]Alamofire:设置网络请求超时时间【timeout】的两种方式
两种方式作用相同,是同一套代码的两种表述. 第一种方式:集聚. 直接设置成员属性(全局属性),这种方法不能灵活修改网络请求超时时间timeout. 声明为成员属性: // MARK: - 设置为全局变 ...
- ubuntu ImageMagick 图像转换工具
ImageMagick(简称 IM)是一个支持 GPL 协议的开源免费软件包.它由一组命令行工具组成的.它可以对超过 100 种的图像格式(包括 DPX, EXR, GIF, JPEG, JPEG-2 ...
- 【雷神源码解析】无基础看懂AAC码流解析,看不懂你打我
一 前言 最近在尝试学习一些视频相关的知识,随便一搜才知道原来国内有雷神这么一个真正神级的人物存在,尤其是在这里(传送门)看到他的感言更是对他膜拜不已,雷神这种无私奉献的精神应当被我辈发扬光大.那写这 ...