动 态 规 划

一、(what?)

二、(why?)

三、(how?)

四、典型例题分析:

例题1:神奇的兔子序列

输入:月数

输出:兔子数

思路:

代码1(函数递归):

#include<iostream>
using namespace std;

int fib(int n)
{
	if(n < 1)
		return -1;
	else if(n == 1|| n == 2)
		return 1;
	else
		return fib(n-1)+fib(n-2);
}

int main()
{
	int n;
	cin>>n;
	cout<<fib(n);
	return 0;
} 

代码2(数组递归):

#include<iostream>
using namespace std;

int fib(int n)
{
	if(n < 1) return -1;
	int F[n+1];
	F[1] = 1, F[2] = 1;
	for(int i = 3; i <= n; i++)
		F[i] = F[i-1]+F[i-2];
	return F[n];
}

int main()
{
	int n;
	cin>>n;
	cout<<fib(n);
	return 0;
} 

例题2:孩子有多像爸爸——最长公共子序列

 暴力搜索

举个简单的暴力搜索的

#include<iostream>
using namespace std;
int main()
{
	char s[7]={'A','B','C','B','A','D','B'};
	
	for(int k=0;k<=7;k++)
	{
		for(int i=k;i<=7;i++)
		{
			for(int j=k;j<i;j++)
			{
				cout<<s[j];
			}
			cout<<endl;
		}	
	}
	
	return 0;
 } 

 显示所有子串:

 求其中一个子串的数组:

#include<iostream>
using namespace std;
int main()
{
	char s[7] = {'A','B','C','B','A','D','B'};
	//char ss[6] = {'B','C','B','A','A','C'};
	
	string str1[100],str2[100];
	int len1=0,len2=0;
	
	for(int k=0;k<=7;k++)
	{
		for(int i=k;i<=7;i++)
		{
			for(int q=k;q<i;q++)
			{
				str1[len1]+=s[q];
			}
			len1++;
		}	
	}	
	for(int k=0;k<len1;k++)
	{
		cout<<str1[k]<<endl;
	}	
	return 0;
 } 

 输出:

题解代码:

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

const int MAX=1000;

char s[MAX],ss[MAX];

string str1[MAX],str2[MAX];

int len1=0,len2=0;

int main()
{
	//char s[7] = {'A','B','C','B','A','D','B'};
	//char ss[6] = {'B','C','B','A','A','C'};
	
	//string str1[100],str2[100];
	//int len1=0,len2=0;
	
	string st1,st2;
	cin>>st1>>st2;
	int i=0,j=0;
	while(i<st1.length())
	{
		s[i]=st1[i];
		i++;
	}
	while(j<st2.length())
	{
		ss[j]=st2[j];
		j++;
	}
	
	//存入第一个子串数组 
	for(int k=0;k<=7;k++)
	{
		for(int i=k;i<=7;i++)
		{
			for(int q=k;q<i;q++)
			{
				str1[len1]+=s[q];
			}
			len1++;
		}	
	}
	/*	
	for(int k=0;k<len1;k++)
	{
		cout<<str1[k]<<endl;
	}	*/
	//存入第二个子串数组
	for(int k=0;k<=6;k++)
	{
		for(int i=k;i<=6;i++)
		{
			for(int q=k;q<i;q++)
			{
				str2[len2]+=ss[q];
			}
			len2++;
		}	
	}	
	/*	
	for(int k=0;k<len2;k++)
	{
		cout<<str2[k]<<endl;
	}	 
	*/
	int temp=0,max=-1000;
	string answer;
	for(int i=0;i<len1;i++)
	{
		string strr1=str1[i];
		for(int j=0;j<len2;j++)
		{
			if(str2[j]==strr1)
			{
				temp=strr1.length();
				if(temp>=max)
				{
					max=temp;
					answer=strr1;
				}
			}
		}	
	} 
	cout<<answer<<endl<<max;	
	return 0;
 } 

结果:

*注:这并不是例题的解法,只是对暴力搜索举个例子,二者并无关联!

原理题的条件子串是从父亲的基因中取一些值并非一定连续!!!

 下面,用动态规划算法解决此问题

算法设计:

图解算法:

 

 

 

 

 

伪代码:

Void LCSL()
{
    int I,j;
    for(I = 1;I <= len1;i++)    //控制s1序列
      for(j = 1;j <= len2;j++)  //控制s2序列
      {
        if(s1[i-1]==s2[j-1])    //字符下标从0开始
        {   //如果当前字符相同,则公共子序列的长度为该字符前的最长公共序列+1
            c[i][j] = c[i-1][j-1]+1;
            b[i][j] = 1;
        }
        else
        {
            if(c[i][j-1]>=c[i-1][j]) //两者找最大值,并记录最优策略来源
            {
                  c[i][j] = c[i][j-1];
                  b[i][j] = 2;
            }
            else
            {
                  c[i][j] = c[i-1][j];
                  b[i][j] = 3;
            }
        }
     }
}

Void print(int I, int j)//根据记录下来的信息构造最长公共子序列(从b[i][j]开始递推)
{
    if(i==0 || j==0) return;
    if(b[i][j]==1)
    {
        print(i-1,j-1);
        cout<<s1[i-1];
    }
    else if(b[i][j]==2)
              print(I,j-1);
          else print(i-1,j);
}

代码:

#include<iostream>
#include<string>
using namespace std;
const int N = 1002;//数组最大长度 
int c[N][N], b[N][N];//c:公共子序列长度。b:答案路径
char s1[N], s2[N];
int len1, len2;


//动态规划查询最大子序列函数 
void LCSL()
{
	int i, j;
	for (i = 1; i <= len1; i++)//控制s1序列
	{
		for (j = 1; j <= len2; j++)//控制s2序列
		{
			//动态规划开始
			if (s1[i - 1] == s2[j - 1])//字符下标从0开始 
			{//如果字符相同,公共子序列的长度为该字符前的最长公共子序列(左上角)+1 
				c[i][j] = c[i - 1][j - 1] + 1;
				b[i][j] = 1;//此情况标记为1 
			}
			else
			{//如果字符不相等的子序列长度 
				if (c[i][j - 1] >= c[i - 1][j])
				{//如果上面的大于左面,子序列长度为上值 
					c[i][j] = c[i][j - 1];
					b[i][j] = 2;//取上值为2 
				}
				else
				{//如果左大于上,取左值 
					c[i][j] = c[i - 1][j];
					b[i][j] = 3;//取左值为3 
				}
			}
		}
	}
	for (i = 0; i <= len1; i++)
	{
		for(j = 0; j <= len2; j++)
		{
			cout << c[i][j];
		}
		cout << endl;
	}
}

//输出最优路径的函数(因为是函数递归,所以经过倒退能得到正序路径) 
void print(int i, int j)//从b[i][j]开始递推 
{
	if (i == 0 || j == 0) return;//如果有一个序列递归完了就结束递归
	if (b[i][j] == 1)
	{//说明此时s1[i-1]=s2[j-1],b[i][j]的值来自c左上角 
		print(i - 1, j - 1);//递归去左上角 
		cout << s1[i - 1];
	}
	else if (b[i][j] == 2)
	{//s1[i-1]与s2[j-1]不等,b[i][j]值来自c上 
		print(i, j - 1);
	}
	else
	{//字符不等取值来自左 
		print(i - 1, j);
	}
}

int main()
{
	int i, j;
	cout << "输入字符串s1:" << endl;
	cin >> s1;
	cout << "输入字符串s2:" << endl;
	cin >> s2;
	len1 = strlen(s1);//求char型数组的长度
	len2 = strlen(s2);

	for (i = 0; i <= len1; i++)
	{
		c[i][0] = 0;//初始化第一行	
	}
	for (j = 0; j <= len2; j++)
	{
		c[0][j] = 0;//初始化第一列	
	}

	LCSL();//求最长子序列
	cout << "最长子序列长度为:" << c[len1][len2] << endl;
	cout << "最长公共子序列是:";
	print(len1, len2);
	return 0;
}

输出: 

例题3:DNA基因鉴定——编辑距离

 算法设计:

算法图解:

 

 

伪代码:

int editdistance(char *str1, char *str2)
{
     int len1 = strlen(str1);      //计算字符串长度
     int len2 = strlen(str2); 
     for(int i=0;i<=len1;i++)      //当第二个串长度为0,编辑距离初始化为i
          d[i][0]= i;
     for(int j=0;j<=len2;j++)      //当第一个串长度为0,编辑距离初始化为j
          d[0][j]=j;
     for(int i=1;i <=len1;i++)     //遍历两个字符串
     {
          for(int j=1;j<=len2;j++)
          {
               int diff;//判断str[i]是否等于str2[j],相等为0,不相等为1
               if(str1[i-1] == str2[j-1]) //相等
                     diff = 0 ;
               else
                     diff = 1 ;
               int temp = min(d[i-1][j] + 1, d[i][j-1] + 1);//先两者取最小值
               d[i][j] = min(temp, d[i-1][j-1] + diff);//再取最小值,
                     //相当于三者取最小值d[i-1][j] + 1, d[i][j-1] + 1,d[i-1][j-1] + diff
          }
     }
     return d[len1][len2];
}

 完整代码:

#include<iostream>
#include<string>
using namespace std;
const int N = 100;
char str1[N],str2[N];
int d[N][N];//d[i][j]表示的str1前i个字符的str2前j个字符的编辑距离

int StrLen(char *s)//求字符串长度 
{
	int i=0;
	while(s[i]!='\0')
	{
		i++;	
	}	
	return i;
} 

int min(int a,int b)
{
	return a<b?a:b; //返回较小值 
}
 
int editdistance(char *str1,char *str2)
{
	int len1=StrLen(str1);
	int len2=StrLen(str2);	
	//初始化
	for(int i=0;i<=len1;i++)
	{//第二个串长度为0,编辑距离初始化为i 
		d[i][0]	= i;
	} 
	for(int j=0;j<=len2;j++)
	{//第二个串长度为0,编辑距离初始化为j
		d[0][j]	= j;
	}
	//遍历两个字符串 
	for(int i=1;i<=len1;i++)
	{
		for(int j=1; j<=len2;j++)
		{
			int diff;//判断字符是否相等,相等不需要编辑+0,不相等+1
			if(str1[i-1] == str2[j-1])
			{
				diff=0;
			}
			else
			{
				diff=1;	
			} 
			int temp=min(d[i-1][j]+1,d[i][j-1]+1);
			d[i][j] = min(temp,d[i-1][j-1]+diff);//连去两次两个求最小值等价于三个求最小值 
		}
	}
	for(int i=0;i<=len1;i++)
	{
		for(int j=0;j<=len2;j++)
		{
			cout<<d[i][j];
		}
		cout<<endl;
	}
	return d[len1][len2]; 
} 
int main()
{
	cin>>str1>>str2;
	cout<<editdistance(str1,str2);
	return 0;
}

 输入输出:

例题4:长江一日游——游艇租赁

算法设计: 

 算法图解:

伪代码:

void rent()
{
     int i,j,k,d;
     for(d=3;d<=n;d++) //将问题分为小规模d
     {
          for(i=1;i<=n-d+1;i++)
               {
                    j=i+d-1;
                    for(k=i+1;k<j;k++)  //记录每一个小规模内的最优解
                    {
                         int temp;
                         temp=m[i][k]+m[k][j];
                         if(temp<m[i][j])
                               {
                                 m[i][j]=temp;
                                 s[i][j]=k;
                               }
                    }
               }
     }
}

 

void print(int i,int j)
{
     if(s[i][j]==0 )
     {
          cout << "--"<<j;
          return ;
     }
     print(i,s[i][j]);
     print(s[i][j],j);
}

 完整代码:

//program 4-3
#include<iostream>
using namespace std;
const int ms = 1000;
int r[ms][ms],m[ms][ms],s[ms][ms];    //i到j站的租金
int n;            //共有n个站点
void rent()
{
     int i,j,k,d;
     for(d=3;d<=n;d++) //将问题分为小规模为d
     {
         for(i=1;i<=n-d+1;i++)
              {
                   j=i+d-1;
                   for(k=i+1;k<j;k++)  //记录每一个小规模内的最优解
                   {
                        int temp;
                        temp=m[i][k]+m[k][j];
                        if(temp<m[i][j])
                             {
                                m[i][j]=temp;
                                s[i][j]=k;
                             }
                   }
              }
     }
}
void print(int i,int j)
{
     if(s[i][j]==0 )
     {
         cout << "--"<<j;
         return ;
     }
     print(i,s[i][j]);
     print(s[i][j],j);
}
int main()
{
     int i,j;
     cout << "请输入站点的个数 n:";
     cin >> n;
     cout << "请依次输入各站点之间的租金:";
     for(i=1;i<=n;i++)
          for(j=i+1;j<=n;++j)
          {
              cin>>r[i][j];
              m[i][j]=r[i][j];
          }
     rent();
     cout << "花费的最少租金为:" <<m[1][n] << endl;
     cout <<"最少租金经过的站点:"<<1;
     print(1,n);
     return 0;
}

输入输出:

例题5:快速计算——矩阵连乘

 算法设计:

图解算法:

 伪代码:

void print(int i,int j)
{
     if( i == j )
     {
         cout <<"A[" << i << "]";
         return ;
     }
     cout << "(";
     print(i,s[i][j]);
     print(s[i][j]+1,j);
     cout << ")";
}

 完整代码:

//program 4-4
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int msize = 100;
int p[msize];
int m[msize][msize],s[msize][msize];
int n;
void matrixchain()
{
     int i,j,r,k;
     memset(m,0,sizeof(m));
     memset(s,0,sizeof(s));
     for(r = 2; r <= n; r++)          //不同规模的子问题
     {
          for(i = 1; i <= n-r+1; i++)
          {
              j = i + r - 1;
              m[i][j] = m[i+1][j] + p[i-1] * p[i] * p[j];  //决策为k=i的乘法次数
              s[i][j] = i;            //子问题的最优策略是i;
              for(k = i+1; k < j; k++) //对从i到j的所有决策,求最优值,记录最优策略
               {
                    int t = m[i][k] + m[k+1][j] + p[i-1] * p[k] * p[j];
                    if(t < m[i][j])
                    {
                          m[i][j] = t;
                          s[i][j] = k;
                    }
               }
          }
     }
}
void print(int i,int j)
{
     if( i == j )
     {
          cout <<"A[" << i << "]";
          return ;
     }
     cout << "(";
     print(i,s[i][j]);
     print(s[i][j]+1,j);
     cout << ")";
}
int main()
{
     cout << "请输入矩阵的个数 n:";
     cin >> n;
     int i ,j;
     cout << "请依次输入每个矩阵的行数和最后一个矩阵的列数:";
     for (i = 0; i <= n; i++ )
          cin >> p[i];
     matrixchain();
     print(1,n);
     cout << endl;
     cout << "最小计算量的值为:" << m[1][n] << endl;
}

 输入输出:

例题6:切呀切披萨——最优三角剖分

例题7:小石子游戏——石子合并

例题8:大卖场购物车——0-1背包问题

 算法设计:

 图解算法:

伪代码:

for(i=1;i<= n;i++)           //计算c[i][j]
          for(j=1;j<=W;j++)
               if(j<w[i])    //当物品的重量大于购物车的容量,则不放此物品
                    c[i][j] = c[i-1][j];
               else          //否则比较此物品放与不放是否能使得购物车内的价值最大
                    c[i][j] = max(c[i-1][j],c[i-1][j-w[i]] + v[i]);
     cout<<"装入购物车的最大价值为:"<<c[n][W]<<endl;

 

//逆向构造最优解
j=W;
for(i=n;i>0;i--)
    if(c[i][j]>c[i-1][j])
    {
         x[i]=1;
         j-=w[i];
    }
    else
        x[i]=0;
cout<<"装入购物车的物品为:";
for(i=1;i<=n;i++)
    if(x[i]==1)
         cout<<i<<"  ";

 完整代码:

//program 4-7
#include <iostream>
#include<cstring>
using namespace std;
#define maxn 10005
#define M 105
int c[M][maxn];         //c[i][j] 表示前i个物品放入容量为j购物车获得的最大价值
int w[M],v[M];          //w[i] 表示第i个物品的重量,v[i] 表示第i个物品的价值
int x[M];               //x[i]表示第i个物品是否放入购物车
int main(){
     int i,j,n,W;       //n表示n个物品,W表示购物车的容量
     cout << "请输入物品的个数n:";
     cin >> n;
     cout << "请输入购物车的容量W:";
     cin >> W;
     cout << "请依次输入每个物品的重量w和价值v,用空格分开:";
     for(i=1;i<=n;i++)
          cin>>w[i]>>v[i];
     for(i=0;i<=n;i++)  //初始化第0列为0
          c[i][0]=0;
     for(j=0;j<=W;j++)  //初始化第0行为0
          c[0][j]=0;
     for(i=1;i<= n;i++) //计算c[i][j]
          for(j=1;j<=W;j++)
               if(j<w[i])  //当物品的重量大于购物车的容量,则不放此物品
                    c[i][j] = c[i-1][j];
               else    //否则比较此物品放与不放是否能使得购物车内的价值最大
                    c[i][j] = max(c[i-1][j],c[i-1][j-w[i]] + v[i]);
     cout<<"装入购物车的最大价值为:"<<c[n][W]<<endl;
     //逆向构造最优解
     j=W;
     for(i=n;i>0;i--)
          if(c[i][j]>c[i-1][j])
          {
               x[i]=1;
               j-=w[i];
          }
          else
               x[i]=0;
     cout<<"装入购物车的物品为:";
     for(i=1;i<=n;i++)
          if(x[i]==1)
               cout<<i<<"  ";
     return 0;
}

输入输出:

例题9:快速定位——最优二叉搜索

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于机器学习的居民消费影响因子分析预测

项目视频讲解: 基于机器学习的居民消费影响因子分析预测_哔哩哔哩_bilibili 主要工作内容: 完整代码: import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns import missingno as msno import warnings warnings.filterwarnin…

Python------列表 集合 字典 推导式(本文以 集合为主)

推导式&#xff1a; 推导式comprehensions&#xff08;又称解析式&#xff09;&#xff0c;是Python的一种独有特性。推导式是可以从一个数据序列 构建 另一个 新的数据序列&#xff08;一个有规律的列表或控制一个有规律列表&#xff09;的结构体。 共有三种推导&#xff…

二十三种设计模式全面解析-当你的对象需要知道其他对象的状态变化时,观察者模式是你的救星!

在软件设计的世界中&#xff0c;有一种设计模式以其简洁而强大的特性闪耀着光芒&#xff0c;它就是——观察者模式&#xff08;Observer Pattern&#xff09;。这个模式它定义了一种一对多的依赖关系&#xff0c;让多个观察者对象同时监听某一个主题对象&#xff0c;为我们创造…

【spring】ApplicationContext的实现

目录 一、ClassPathXmlApplicationContext1.1 说明1.2 代码示例1.3 截图示例 二、FileSystemXmlApplicationContext2.1 说明2.2 代码示例2.3 加载xml的bean定义示例 三、AnnotationConfigApplicationContext3.1 说明3.2 代码示例3.3 截图示例 四、AnnotationConfigServletWebSe…

Git安装与常用命令

Git简介&#xff1a; Git是一个开源的分布式版本控制系统&#xff0c;用于敏捷高效地处理任何或大或小的项目。Git是Linus Torvalds为了帮助管理Linux内核开发而开发的一个开放源代码的版本控制软件。Git与常用的版本控制工具CVS、Subversion等不同&#xff0c;它采用了分布式…

CF1899 G. Unusual Entertainment [二维数点/二维偏序]

传送门:CF [前题提要]:没什么好说的,区域赛爆炸之后发愤加训思维题.秒了div3 A~F的脑筋急转弯,然后被G卡了,树剖dfs序的想法已经想到了,题目也已经化简为两个线段是否存在一个合法位置了.但是MD不会二维数点,用一个树剖扫描线搞来搞去最后还是Tle.果然如下图所说:科技还是十分…

Netty传输object并解决粘包拆包问题

⭐️ 前言 大家好&#xff0c;笔者之前写过一篇文章&#xff0c;《Netty中粘包拆包问题解决探讨》&#xff0c;就Netty粘包拆包问题及其解决方案进行了探讨&#xff0c;本文算是这篇博客的延续。探讨netty传输object的问题。 本文将netty结合java序列化来传输object并解决粘包…

3dMax2024新功能和工作流增强功能速览

3dMax2024新功能和工作流增强功能速览 Autodesk发布的3dMax2024引入了一系列新功能和工作流增强功能&#xff0c;如下所示&#xff1a; 更新的“指定控制器”卷展栏&#xff1a;这个现代化的功能为动画师提供了更高效的工作方式&#xff0c;简化了他们的动画流程。 布尔修饰符…

【DevOps】Git 图文详解(三):常用的 Git GUI

Git 图文详解&#xff08;三&#xff09;&#xff1a;常用的 Git GUI 1.SourceTree2.TortoiseGit3.VSCode 中的 Git 如果不想用命令行工具&#xff0c;完全可以安装一个 Git 的 GUI 工具&#xff0c;用的更简单、更舒服。不用记那么多命令了&#xff0c;极易上手&#xff0c;不…

二、ST-Link驱动的安装

1、灵动mm32单片机 (1)上海灵动微电子股份有限公司 (2)mm32单片机支持ST-Link下载程序。 2、ST-Link驱动的安装 (1)下载地址 ST-Link 官网下载地址 (2)点击获取软件下载ST-Link驱动。(需要登陆ST官网账户) (3)下载后解压&#xff0c;根据电脑位数安装 .exe 文件即可。 6…

若依前后端分离版,快速上手

哈喽~大家好&#xff0c;这篇来看看若依前后端分离版&#xff0c;快速上手&#xff08;肝了挺久的&#xff09;。 &#x1f947;个人主页&#xff1a;个人主页​​​​​ &#x1f948; 系列专栏&#xff1a;【Springboot和Vue全栈开发】…

Javaweb之Vue指令案例的详细解析

2.3.5 案例 需求&#xff1a; 如上图所示&#xff0c;我们提供好了数据模型&#xff0c;users是数组集合&#xff0c;提供了多个用户信息。然后我们需要将数据以表格的形式&#xff0c;展示到页面上&#xff0c;其中&#xff0c;性别需要转换成中文男女&#xff0c;等级需要…

QTableWidget——表格的合并与拆分

一、整体思路 表格的操作使用QTableView::setSpan可以实现表格的行和列的合并 表格拆分没有对应的处理函数 主要思路&#xff1a;对表格的属性、内容、拆分与合并的参数进行存储&#xff0c;在进行拆分时对表格内容进行重新创建&#xff08;不考虑效率问题&#xff09; 二、效…

MyBatis使用注解操作及XML操作

文章目录 1. 注解操作1.1 打印日志1.2 参数传递1.3 增&#xff08;Insert&#xff09;注意1&#xff1a;重命名注意2&#xff1a;返回主键 1.4 删&#xff08;Delete&#xff09;1.5 改&#xff08;Update&#xff09;1.6 查&#xff08;Select&#xff09;1. 配置&#xff0c;…

Windows10下Tomcat8.5安装教程

文章目录 1.首先查看是否安装JDK。2.下载3.解压到指定目录&#xff08;安装路径&#xff09;4.启动Tomcat5.常见问题5.1.如果出现报错或者一闪而过5.2.Tomcat乱码 1.首先查看是否安装JDK。 CMD窗口输入命令 java -version 2.下载 历史版本下载地址&#xff1a;https://archi…

量化交易:传统小市值策略 VS AI市值策略

在BigQuant平台上可以快速开发股票传统策略和股票AI策略&#xff0c;今天拿市值因子来练手&#xff0c;看看两个策略在2015-01-01到2016-12-31这两年时间各自的收益风险情形。 市值因子是国内股票市场能够带来超额收益的alpha因子&#xff0c;已经被验证为长期有效的因子&…

向pycdc项目提的一个pr

向pycdc项目提的一个pr 前言 pycdc这个项目&#xff0c;我之前一直有在关注&#xff0c;之前使用他反编译python3.10项目&#xff0c;之前使用的 uncompyle6无法反编译pyhton3.10生成的pyc文件&#xff0c;但是pycdc可以&#xff0c;但是反编译效果感觉不如uncompyle6。但是版…

Appium混合页面点击方法tap的使用

原生应用开发&#xff0c;是在Android、IOS等移动平台上利用官方提供的开发语言、开发类库、开发工具进行App开发&#xff1b;HTML5&#xff08;h5&#xff09;应用开发&#xff0c;是利用Web技术进行的App开发。目前&#xff0c;市面上很多app都是原生和h5混合开发&#xff0c…

SELinux

目录 1.概述 1.1.概念 1.2.作用 1.3. SELinux与传统的权限区别 2. SELinux工作原理 2.1.名词解释 2.1.1.主体(Subject) 2.1.2.目标(Object) 2.1.3.策略(Policy) 2.1.4.安全上下文(Security Context) 2.2.文件安全.上下文查看 2.2.1.命令: 2.2.2.分析 3. **SELinu…