(Week 7)动态规划(C++)

news2024/12/27 16:14:33

目录

  • [NOIP2005 普及组] 采药(C++,动态规划)
    • 题目描述
    • 输入格式
    • 输出格式
    • 样例 #1
      • 样例输入 #1
      • 样例输出 #1
    • 提示
    • 解题思路:
  • 最长上升子序列(C++,Dilworth,贪心)
    • 题目描述
    • 输入格式
    • 输出格式
    • 样例 #1
      • 样例输入 #1
      • 样例输出 #1
    • 提示
    • 解题思路:
  • 最大子段和(C++,DP)
    • 题目描述
    • 输入格式
    • 输出格式
    • 样例 #1
      • 样例输入 #1
      • 样例输出 #1
    • 提示
        • 样例 1 解释
        • 数据规模与约定
    • 解题思路:
  • LCS
    • 题目描述:
    • 输入格式:
    • 输出格式:
    • 样例 #1
      • 样例输入 #1
      • 样例输出 #1
    • 样例 #2
      • 样例输入 #2
      • 样例输出 #2
    • 样例 #3
      • 样例输入 #3
      • 样例输出 #3
    • 样例 #4
      • 样例输入 #4
      • 样例输出 #4
    • 说明/提示:
    • 解题思路:

[NOIP2005 普及组] 采药(C++,动态规划)

题目描述

辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。”

如果你是辰辰,你能完成这个任务吗?

输入格式

第一行有 2 2 2 个整数 T T T 1 ≤ T ≤ 1000 1 \le T \le 1000 1T1000)和 M M M 1 ≤ M ≤ 100 1 \le M \le 100 1M100),用一个空格隔开, T T T 代表总共能够用来采药的时间, M M M 代表山洞里的草药的数目。

接下来的 M M M 行每行包括两个在 1 1 1 100 100 100 之间(包括 1 1 1 100 100 100)的整数,分别表示采摘某株草药的时间和这株草药的价值。

输出格式

输出在规定的时间内可以采到的草药的最大总价值。

样例 #1

样例输入 #1

70 3
71 100
69 1
1 2

样例输出 #1

3

提示

【数据范围】

  • 对于 30 % 30\% 30% 的数据, M ≤ 10 M \le 10 M10
  • 对于全部的数据, M ≤ 100 M \le 100 M100

【题目来源】

NOIP 2005 普及组第三题

解题思路:

首先根据下面一组数据就可以排除贪心算法(尽量选取 v a l u e t i m e \frac{value}{time} timevalue高的)

4 3
2 6
2 3
3 4

所以我们采用递归的方式寻找最大值,递归的思路就是:

//dfs(t, m)会return前m株herb的max_value
int dfs(int t, int m) {//t为当前剩余时间,m代表当前是几号草药
    //返回不选或者选中的最大值
	return max(dfs(t, m - 1)/*不选*/, dfs(t - herb_arr[m].time, m - 1) + herb_arr[m].value/*选*/);
}

再加上边界判断、条件判断

int dfs(int t, int m) {
	if (m == -1 || t == 0)
		return 0;
	else if (herb_arr[m].time > t)
		return dfs(t, m - 1);
	else 
		return max(dfs(t, m - 1), dfs(t - herb_arr[m].time, m - 1) + herb_arr[m].value);
}

然后计算一下时间复杂度会发现是o( 2 n 2^n 2n),显然不可接受

所以进行记忆化搜索,时间复杂度是o(T*M)

int max_value[1001][101] = { 0 };
memset(max_value, -1, sizeof(int) * 1001 * 101);

int dfs(int t, int m) {
	if (m == -1 || t == 0) 
		return 0;
	else if (max_value[t][m] != -1) 
		return max_value[t][m];//记忆
	else if (herb_arr[m].time > t) 
		return max_value[t][m] = dfs(t, m - 1);
	else 
		return max_value[t][m] = max(dfs(t, m - 1), dfs(t - herb_arr[m].time, m - 1) + herb_arr[m].value);
}

实现的完整代码如下

#include <iostream>
#include <memory.h>
using namespace std;

struct herb {
	int time;
	int value;
};

struct herb herb_arr[100];
int max_value[1001][101] = { 0 };

int dfs(int t, int m) {
	if (m == -1 || t == 0) return 0;
	else if (max_value[t][m] != -1) return max_value[t][m];
	else if (herb_arr[m].time > t) return max_value[t][m] = dfs(t, m - 1);
	else return max_value[t][m] = max(dfs(t, m - 1), dfs(t - herb_arr[m].time, m - 1) + herb_arr[m].value);
}

int main() {
	int T, M;
	cin >> T >> M;
	for (int i = 0; i < M; i++) cin >> herb_arr[i].time >> herb_arr[i].value;
	memset(max_value, -1, sizeof(int) * 1001 * 101);

	cout << dfs(T, M - 1);
	return 0;
}

最长上升子序列(C++,Dilworth,贪心)

题目描述

这是一个简单的动规板子题。

给出一个由 n ( n ≤ 5000 ) n(n\le 5000) n(n5000) 个不超过 1 0 6 10^6 106 的正整数组成的序列。请输出这个序列的最长上升子序列的长度。

最长上升子序列是指,从原序列中按顺序取出一些数字排在一起,这些数字是逐渐增大的。

输入格式

第一行,一个整数 n n n,表示序列长度。

第二行有 n n n 个整数,表示这个序列。

输出格式

一个整数表示答案。

样例 #1

样例输入 #1

6
1 2 4 1 3 4

样例输出 #1

4

提示

分别取出 1 1 1 2 2 2 3 3 3 4 4 4 即可。

解题思路:

本题其实考察的是动态规划,我也试着去动态规划了,但emmm还是定理好用

关于Dilworth定理,举几个例子就明白了

最长上升子序列长度(<) == 最少不上升子序列数目( ≥ \geq )

最长不下降子序列长度( ≤ \leq ) == 最少下降子序列数目(>)

最长下降子序列长度(>) == 最少不下降子序列数目( ≤ \leq )

最长不上升子序列长度( ≥ \geq ) == 最少上升子序列数目(<)

还可以推广,不只是大小关系,只要是”相反“的两个关系就可以,但“相反”的两个关系需要满足三个条件

(1)自反性: a ≤ a a \leq a aa

(2)反对称性: a ≤ b , b ≤ a , a = b a \leq b, b\leq a, a = b ab,ba,a=b

(3)传递性: a ≤ b , b ≤ c , a ≤ c a \leq b, b \leq c, a \leq c ab,bc,ac

正面求解上面四个例子左侧的问题不太容易,但是右边都可以直接贪心解决

以本题为例,贪心策略如下:

创建一个数组,然后读入一个元素(不是读到数组中)

如果数组中没有比这个元素大的元素,那么将这个元素添加到数组尾

如果有,那么寻找比这个元素大的最小元素,然后把这个元素覆盖

这个过程不需要排序就可以实现,可以思考一下为什么

最后数组中元素的数目即为所求解

AC代码如下

#include <iostream>
#include <vector>
using namespace std;

vector<int> not_upper_arr;

int main() {
	int n, num;
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> num;
		if (not_upper_arr.empty() || not_upper_arr.back() < num) not_upper_arr.push_back(num);
		else {
			size_t j = not_upper_arr.size();
			while (--j < not_upper_arr.size() && not_upper_arr[j] >= num);
			not_upper_arr[++j] = num;
		}
	}

	cout << not_upper_arr.size();
	return 0;
}

最大子段和(C++,DP)

题目描述

给出一个长度为 n n n 的序列 a a a,选出其中连续且非空的一段使得这段和最大。

输入格式

第一行是一个整数,表示序列的长度 n n n

第二行有 n n n 个整数,第 i i i 个整数表示序列的第 i i i 个数字 a i a_i ai

输出格式

输出一行一个整数表示答案。

样例 #1

样例输入 #1

7
2 -4 3 -1 2 -4 3

样例输出 #1

4

提示

样例 1 解释

选取 [ 3 , 5 ] [3, 5] [3,5] 子段 { 3 , − 1 , 2 } \{3, -1, 2\} {3,1,2},其和为 4 4 4

数据规模与约定

  • 对于 40 % 40\% 40% 的数据,保证 n ≤ 2 × 1 0 3 n \leq 2 \times 10^3 n2×103
  • 对于 100 % 100\% 100% 的数据,保证 1 ≤ n ≤ 2 × 1 0 5 1 \leq n \leq 2 \times 10^5 1n2×105 − 1 0 4 ≤ a i ≤ 1 0 4 -10^4 \leq a_i \leq 10^4 104ai104

解题思路:

通过样例输入进行说明

首先读入2,把2作为前缀

然后读入-4,2+(-4)=-2>-4,所以如果-4是最大子段的一部分,2一定也是最大子段的一部分

再读入3,3+(-2)=1<3,所以如果3是最大子段的一部分,2和-4一定不是最大子段的一部分

再读入-1,3+(-1)=2<3,所以如果-1是最大子段的一部分,3一定也是最大子段的一部分

再读入2,2+2=4>2,所以如果2是最大子段的一部分,3和-1一定也是最大子段的一部分

再读入-4,4+(-4)=0>-4,所以如果-4是最大子段的一部分,3、-1、2一定也是最大子段的一部分

最后读入3,0+3=3==3,所以如果3是最大子段的一部分,3、-1、2、-4一定不是最大子段的一部分

本质就是尝试给每一个数连接一个前缀,使这个数变得比自己大,如果比自己小,那么就不连接这个前缀

每次比较连接前缀后和不连接前缀二者的大小时,我们都保证了得到的是最大的前缀,同时有可能我们得到的最大前缀就是所谓的最大子段

所以本题采用的策略并不能保证最后得到的是最大子段,但我们一定曾经得到过最大子段

再加上一个变量max_num,比较每次连接的结果并存入其中

所以在读入3之后虽然我们丢弃了2和-4,但我们已经把22、-4这两个子段中最大者存入了max_num

最后只需要输出max_num即可

AC代码如下

#include <iostream>
using namespace std;

int num_arr[2] = { 0 };
int max_num = 0;

int main() {
	int n, temp;
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> temp;
		if (i < 1) {
			max_num = temp;
			num_arr[0] = temp;
			continue;
		}
		num_arr[i % 2] = max(temp, temp + num_arr[(i + 1) % 2]);
		max_num = num_arr[i % 2] > max_num ? num_arr[i % 2] : max_num;
	}

	cout << max_num;
	return 0;
}

LCS

题目描述:

给定一个字符串 s s s 和一个字符串 t t t ,输出 s s s t t t 的最长公共子序列。

输入格式:

两行,第一行输入 s s s ,第二行输入 t t t

输出格式:

输出 s s s t t t 的最长公共子序列。如果有多种答案,输出任何一个都可以。

样例 #1

样例输入 #1

axyb
abyxb

样例输出 #1

axb

样例 #2

样例输入 #2

aa
xayaz

样例输出 #2

aa

样例 #3

样例输入 #3

a
z

样例输出 #3


样例 #4

样例输入 #4

abracadabra
avadakedavra

样例输出 #4

aaadara

说明/提示:

数据保证 s s s t t t 仅含英文小写字母,并且 s s s t t t 的长度小于等于3000。

解题思路:

设有两个字符串 s = < s 1 , s 2 , … , s n > s=<s_1,s_2,\dots,s_n> s=<s1,s2,,sn> t = < t 1 , t 2 , … , t m > t=<t_1,t_2,\dots,t_m> t=<t1,t2,,tm>,s和t的LCS为 z = < z 1 , z 2 , … , z k > z=<z_1,z_2,\dots,z_k> z=<z1,z2,,zk>

如果 s n = t m s_n = t_m sn=tm,那么 s n − 1 s_{n-1} sn1 t m − 1 t_{m-1} tm1的LCS是 z k − 1 z_{k-1} zk1

**如果 s n ≠ t m s_n \ne t_m sn=tm,那么 s n − 1 s_{n-1} sn1 t t t(或者 s s s t n − 1 t_{n-1} tn1)的LCS是 z ​ ∗ ∗ z​** z

根据上面的说明,可以得出以下递推公式

l e n [ i ] [ j ] = { 0 , i   =   0 或 j   =   0 l e n [ i − 1 ] [ j − 1 ] + 1 , s i = t j m a x { l e n [ i − 1 ] [ j ] ,   l e n [ i ] [ j − 1 ] } , s i ≠ t j len[i][j]=\begin{cases}0,&i\ =\ 0或j\ =\ 0\\[2ex]len[i-1][j-1]+1, &s_i=t_j\\[2ex]max\{len[i-1][j],\ len[i][j-1]\},&s_i\ne t_j\end{cases} len[i][j]= 0,len[i1][j1]+1,max{len[i1][j], len[i][j1]},i = 0j = 0si=tjsi=tj

实现代码如下

#include <iostream>
using namespace std;
const int max_n = 3000;

string s, t;

string dfs(int i, int j) {
	if (i == -1 || j == -1) return "";
	else if (s[i] == t[j]) return dfs(i - 1, j - 1) + s[i];
	else {
		string temp_1 = dfs(i - 1, j), temp_2 = dfs(i, j - 1);
		return temp_1.size() > temp_2.size() ? temp_1 : temp_2;
	}
}

int main() {
	cin >> s >> t;
	cout << dfs(int(s.size()) - 1, int(t.size()) - 1);
	return 0;
}

但这段代码会TLE,需要进行动态优化

关于动态优化的策略,这里举例进行说明

s="adca",t="eacb"

lcs="ac"

第一次ret
请添加图片描述
第二次ret
请添加图片描述
第三次ret
请添加图片描述
第四次ret
请添加图片描述
第五次ret
请添加图片描述
到这里应该就能看出来可以优化的地方了:第2行第4列被搜索了两次

但是并不是简单记住这次搜索后的结果就可以了
请添加图片描述
对于第二行第四列,我们可以得到不同的搜索结果

那么会想到再多记录一些信息(如记录i和j)进行判断,但那样先不说优化效果不好,占用的空间也是不可接受的

所以进一步思考,(1)我们可以优化的情形是 s i ≠ t j s_i\ne t_j si=tj时(2) s i ≠ s j s_i\ne s_j si=sj时,来到同一格子的方式只有两种

那么我们只要选择左与上中较大者即可

但问题又来了,左与上可能是空格子,原因是当 s i = t j s_i=t_j si=tj时会发生跳转

再思考一下会发现,(3)如果 s n = t m s_n = t_m sn=tm,那么 s n − 1 s_{n-1} sn1 t m − 1 t_{m-1} tm1的LCS是 z k − 1 z_{k-1} zk1,与此同时 s n − 1 和 t m s_{n-1}和t_m sn1tm(或 s n 和 t m − 1 s_n和t_{m-1} sntm1)的LCS也同样是 z k − 1 z_{k-1} zk1

那么就可以在 s i = t j s_i=t_j si=tj时将其右和下的格子都填上跳转后的结果

至此,动态优化策略说明完成,优化后的策略如下:

用for循环遍历每一个格子

如果 s i = t j s_i=t_j si=tj,将上方格子的值+1填入,同时填入右(这里不填入下,也可以思考一下为什么)

如果 s i ≠ t j s_i\ne t_j si=tj,选择左和上的格子中较大者填入

(然后emm觉得优化后和优化前好像都不是一道题了)

之所以 s i = t j s_i=t_j si=tj时直接取上方格子的值,是因为此时临近格子的值一定是相同的,可以自行用递推证明一下为什么

AC代码如下

#include <iostream>
#include <string>
#include <memory.h>
using namespace std;
const int max_n = 3000;

string s, t;
short num_arr[max_n + 1][max_n + 1] = { 0 };
string str_arr[max_n + 1][max_n + 1];

int main() {
	cin >> s >> t;
	memset(num_arr, -1, sizeof(short) * max_n * max_n);
	for (int i = s.size(); i >= 0; i--) {
		for (int j = t.size(); j >= 0; j--) {
			if (i == s.size() || j == t.size()) {//初始化
				num_arr[i][j] = 0;
				str_arr[i][j] = "";
				continue;
			}

			if (num_arr[i][j] != -1) continue;//访问过
			
			if (s[i] == t[j]) {//s_i == t_j
				str_arr[i][j] = s[i] + str_arr[i + 1][j];
				num_arr[i][j] = num_arr[i + 1][j] + 1;
				if (j - 1 > -1) {//尝试填充右
					str_arr[i][j - 1] = str_arr[i][j];
					num_arr[i][j - 1] = num_arr[i][j];
				}
			}
			else {//s_i != t_j
				if (num_arr[i][j + 1] > num_arr[i + 1][j]) {//比较并填充左、上较大者
					str_arr[i][j] = str_arr[i][j + 1];
					num_arr[i][j] = num_arr[i][j + 1];
				}
				else {
					str_arr[i][j] = str_arr[i + 1][j];
					num_arr[i][j] = num_arr[i + 1][j];
				}
			}
		}
	}
	cout << str_arr[0][0];
	return 0;
}

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

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

相关文章

一文盘点Zebec生态的收益模型

随着加密市场逐渐陷入低谷&#xff0c;曾经火热的NFT、GameFi等赛道都陷入了沉寂。投资者目前很难在加密市场中获得可观的收益&#xff0c;而在整体加密市场发展局势不明朗的情况下&#xff0c;行业目前缺乏发展动力。 目前&#xff0c;以流支付为主要定位的Zebec生态&#xff…

Java 基础语法

一个 Java 程序可以认为是一系列对象的集合&#xff0c;而这些对象通过调用彼此的方法来协同工作。下面简要介绍下类、对象、方法和实例变量的概念。 对象&#xff1a;对象是类的一个实例&#xff0c;有状态和行为。例如&#xff0c;一条狗是一个对象&#xff0c;它的状态有&a…

Tomcat 9.0 安装及配置教程(win10系统)

一、前言 Tomcat 服务器是一个开源的轻量级Web应用服务器&#xff0c;在中小型系统和并发量小的场合下被普遍使用&#xff0c;是开发和调试Servlet、JSP 程序的首选。 二、安装前准备 1.确保安装过jdk&#xff0c;安装过可跳过。 如果没有安装可以先安装一下win10下JDK 官方中…

品优购首页布局-头部

10. 品优购首页布局 效果图&#xff1a; 项目结构如下&#xff1a; 命名集合&#xff1a; 名称说明快捷导航栏shortcut头部header标志logo购物车shopcar搜索search热点词hotwrods导航nav导航左侧dorpdown 包含 .dd .dt导航右侧navitems 1). shortcut 制作 通栏的盒子 命名为sho…

网络协议与攻击模拟 | APR_TCP | 系统性学习 | 无知的我费曼笔记

文章目录网络协议与攻击模拟-APR协议网络协议与攻击模拟-实施ARP攻击与欺骗实施ARP攻击实施ARP欺骗网络协议与攻击模拟-TCP三次握手网络协议与攻击模拟-APR协议 APR协议的作用 解析IP地址为MAC地址。从而进行二层数据交互 ARP工作流程 ARP请求 ARP响应 APR的报文格式 在W…

vue——将原生事件和属性绑定到组件

再vue官方文档 将原生事件绑定到组件 中有如下代码描述&#xff1a; 1. v-bind“$attrs” 以html原生属性的形式批量绑定父组件传过来的属性到任意位置&#xff0c; 例如&#xff0c;一些ui组件或者原生input标签需要一些属性来完成某些功能&#xff0c;例如 <input typ…

Linux安装Jenkins(Java11最新版)

文章目录♈️查看java版本♉️1.下载♊️2.上传到服务器♋️3.启动♌️4.记住密码♍️5.解锁Jenkins♎️6.修改插件安装地址♏️7.安装插件♐️8.登录♐️9.修改密码注意&#xff0c;这里是需要java环境的&#xff0c;如果没有java环境请参考 Linux安装Java环境 ♈️查看java版…

「集合底层」Vector底层结构及源码剖析

「集合源码」Vector底层结构及源码剖析 文章目录「集合源码」Vector底层结构及源码剖析一、基本介绍二、类继承关系三、Vector特性四、底层源码分析1、四个构造器2. 添加一个元素的过程以及扩容机制五、Vector与ArrayList共同点区别一、基本介绍 Vector 是一个矢量队列&#x…

【开发指南】AR Foundation 扫描

开发平台&#xff1a;Unity 2020 版本以上 编程平台&#xff1a;Visual Studio 2022 面向平台&#xff1a;IOS 设备   一、本文聚焦问题点 使用哪种 API 完成相机权限的获取如何进行画面跟踪对象的捕获。 对深入了解AR的开发者尤为重要。但只是从应用目的上&#xff0c;只需要…

C++PrimerPlus 第八章 函数探幽-8.5 函数模板

目录 8.5 函数模板 8.5.1 重载的模板 8.5.2 模板的局限性 8.5.3 显式具体化 8.5.3.1 第三代具体化&#xff08;ISO/ANSI C标准&#xff09; 8.5.3.2 显式具体化示例 8.5.4 实例化和具体化 8.5.5 编译器选择使用哪个函数版本 8.5.5.1 完全匹配和最佳匹配 8.5.5.2 部分…

计算机毕设Python+Vue学生风采网(程序+LW+部署)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【Python学习记录】numpy数组用法整理

✨ 博客主页&#xff1a;小小马车夫的主页 ✨ 所属专栏&#xff1a;Python学习记录 文章目录前言一、numpy数组创建1、numpy.array创建数组2、从已有数组中创建数组二、numpy创建数组初始化1、numpy.zero2、numpy.ones3、numpy.arange4、numpy.linspace5、numpy.random三、nump…

Mentor-dft 学习笔记 day44-Low-Power Design Test

Low-Power Testing Overview Tessent Scan支持启用低功耗测试的操作。 •在存在孤立cell的情况下插入专用包装cell。 •根据驱动的逻辑和电源域的优先级将专用包装单元分配给电源域。 低功耗设计流程包括以下步骤&#xff1a; 1.在CPF/UPF文件中指定低功耗数据规范。 2.在设计…

[附源码]计算机毕业设计Python的校园报修平台(程序+源码+LW文档)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

RequestResponse

Request Request继承体系 Request获取请求数据 获取请求数据 通用方式获取请求参数 WebServlet("/req1") public class req1 extends HttpServlet {Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOE…

电脑怎么隐藏文件夹?6个步骤完成!

在日常办公使用电脑的过程中&#xff0c;总会出现各种问题。比如&#xff1a;电脑怎么隐藏文件夹&#xff1f;当我们需要这些数据时&#xff0c;我们又该如何恢复&#xff1f;为了解决这些问题&#xff0c;小编在这里总结了6个操作步骤来隐藏文件夹数据的方法。让我们一起来看看…

【代码随想录】Day34链表:力扣203,707,206,142,面试0207

目录 基本知识 概念、类型、存储方式&#xff1a; 定义 操作 性能分析 经典方法 虚拟头结点 思路 例题&#xff1a;力扣203 链表的基本操作 思路 例题&#xff1a;力扣707 反转链表 思路 例题&#xff1a;力扣206 删除倒数第N个结点 思路&#xff1a; 例题&am…

jsp+ssm计算机毕业设计-东湖社区志愿者管理平台【附源码】

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; JSPSSM mybatis Maven等等组成&#xff0c;B/S模式 Mave…

[附源码]计算机毕业设计Python的在线作业批改系统(程序+源码+LW文档)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

tomcat 服务突然停止、日志排查以及解决方案

文章目录一、服务停止调研1. jvm排查2. 日志排查3. 推测与ssh会话有关二、ssh会话强制退出验证2.1. 手动强制关闭进程12.2. 手动强制关闭进程22.3. 总结归纳与解决方案一、服务停止调研 1. jvm排查 有可能是jvm配置参数导致的&#xff0c;然后在/var/log和/app/apache-tomcat…