一:线性dp
概念:
动态规划是运筹学的一个分支,是求解决策过程最优化的数学方法。
动态规划是通过拆分问题,定义问题状态和状态之间的关系使得问题能够以递推(或者说分治)的方法去解决。
解决策略:
1)最优化原理:如果问题的最优解包含的子问题的解也是最优的,就称该问题又最有子结构,既满足最优化原理。
2)无后效性:某阶段状态一旦确定,就不受这个状态以后的决策影响。也就是说,某状态以后的过程不会影响以前的状态,至于当前状态有关。
3)有重叠子问题:即子问题之间不是独立的,一个字问题在下一阶段决策中可能多次被用到。(该性质并不是动态规划的必要条件,但如果没有这条性质,
动态规划算法和其他算法相比就不具备优势)
解决问题步骤:
1.拆分问题
把原问题分解为若干个子问题,子问题和原问题形式相同或类似,只不过规模变小了。子问题都解决,原问题即解决(数字三角形例)。
子问题的解一旦求出就会被保存,所以每个子问题只需求 解一次。
2.找状态(初始值)
在用动态规划解题时,我们往往将和子问题相关的各个变量的一组取值,称之为一个“状 态”。一个“状态”对应于一个或多个子问题, 所谓某个“状态”下的“值”,就是这个“状 态”所对应的子问题的解。
所有“状态”的集合,构成问题的“状态空间”。“状态空间”的大小,与用动态规划解决问题的时间复杂度直接相关。
整个问题的时间复杂度是状态数目乘以计算每个状态所需时间。在数字三角形里每个“状态”只需要经过一次,且在每个状态上作计算所花的时间都是和N无关的常数。
还需要确定一些(初始状态)边界状态的值。
3.状态转移方程
其实动态规划就好比中学时候学的通项公式,找到这个通项公式之后每次递推就可以取得最后的结果。
用动态规划能写的题基本上用递归的方法都可以。
递归到动规的一般转化方法
递归函数有n个参数,就定义一个n维的数组,数组的下标是递归函数参数的取值范围,数组元素的值是递归函数的返回值,这样就可以从边界值开始, 逐步填充数组,相当于计算递归函数值的逆过程。
1.最长上升子序列
子序列:字符的子序列指的是从给定的字符序列中随意的(不一定连续)的曲调若干个字符(也可能一个也不去掉)最后形成的字符序列。
eg:
给你一个长度为n的序列,求其最长上升子序列。
//*****LIS
#include<bits/stdc++.h>
using namespace std;
int a[10010];
int dp[10010];
int main()
{
int n;
while(cin>>n&&n)
{
for(int i=0;i<n;i++)
{
cin>>a[i];
dp[i]=1;
}
int ans=0;
for(int i=1;i<n;i++)
{
for(int j=0;j<i;j++)
if(a[j]<a[i])
dp[i]=max(dp[j]+1,dp[i]);
ans=max(ans,dp[i]);
}
cout<<ans<<endl;
}
return 0;
}
//2 5 3 7 4 2
推荐题目链接:http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=17
2.求最长上升子序列的长度
//*****LIS nlogn
#include<bits/stdc++.h>
using namespace std;
const int INF=9999999;
int dp[100];//dp[i]表示长度为i+1的子序列末尾元素最小值;
int a[100];
int main()
{
int n;
while(cin>>n&&n)
{
for(int i=0;i<n;i++)
{
cin>>a[i];
dp[i]=INF;
}
for(int i=0;i<n;i++)
*lower_bound(dp,dp+n,a[i])=a[i];//找到>=a[i]的第一个元素,并用a[i]替换;
cout<<lower_bound(dp,dp+n,INF)-dp<<endl;//找到第一个INF的地址减去首地址就是最大子序列的长度;
}
return 0;
}
/*
2 1 5 3 6 4 8 9 7
1 3 4 7 9
1 2 3 4 5
1 3 4 7 9
*/
3.最长公共子序列
题目链接:http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=36
大意:给两个字符串,要求求出最长的公共子序列,求出的公共子序列在每个给定的字符串中可不连续
//*******LCS #include<bits/stdc++.h> using namespace std; string s1,s2,s3; ][]; int len1,len2; int main() { while(cin>>s1>>s2) { memset(dp,,sizeof(dp)); len1=s1.length(); len2=s2.length(); ; i<len1;i++) ; j<len2;j++) { if(s1[i]==s2[j]) dp[i+][j+]=dp[i][j]+; else dp[i+][j+]=max(dp[i+][j],dp[i][j+]); } cout<<dp[len1][len2]<<endl; } ; }
最后推荐两个写dp的博客:
https://blog.csdn.net/baidu_28312631/article/details/47418773
https://blog.csdn.net/baidu_28312631/article/details/47426445
一:线性dp的更多相关文章
- LightOJ1044 Palindrome Partitioning(区间DP+线性DP)
问题问的是最少可以把一个字符串分成几段,使每段都是回文串. 一开始想直接区间DP,dp[i][j]表示子串[i,j]的答案,不过字符串长度1000,100W个状态,一个状态从多个状态转移来的,转移的时 ...
- Codeforces 176B (线性DP+字符串)
题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28214 题目大意:源串有如下变形:每次将串切为两半,位置颠倒形成 ...
- hdu1712 线性dp
//Accepted 400 KB 109 ms //dp线性 //dp[i][j]=max(dp[i-1][k]+a[i][j-k]) //在前i门课上花j天得到的最大分数,等于max(在前i-1门 ...
- 动态规划——线性dp
我们在解决一些线性区间上的最优化问题的时候,往往也能够利用到动态规划的思想,这种问题可以叫做线性dp.在这篇文章中,我们将讨论有关线性dp的一些问题. 在有关线性dp问题中,有着几个比较经典而基础的模 ...
- POJ 2479-Maximum sum(线性dp)
Maximum sum Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 33918 Accepted: 10504 Des ...
- poj 1050 To the Max(线性dp)
题目链接:http://poj.org/problem?id=1050 思路分析: 该题目为经典的最大子矩阵和问题,属于线性dp问题:最大子矩阵为最大连续子段和的推广情况,最大连续子段和为一维问题,而 ...
- nyoj44 子串和 线性DP
线性DP经典题. dp[i]表示以i为结尾最大连续和,状态转移方程dp[i] = max (a[i] , dp[i - 1] + a[i]) AC代码: #include<cstdio> ...
- 『最大M子段和 线性DP』
最大M子段和(51nod 1052) Description N个整数组成的序列a[1],a[2],a[3],-,a[n],将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的.如果M &g ...
- 『最长等差数列 线性DP』
最长等差数列(51nod 1055) Description N个不同的正整数,找出由这些数组成的最长的等差数列. 例如:1 3 5 6 8 9 10 12 13 14 等差子数列包括(仅包括两项的不 ...
- cf909C 线性dp+滚动数组好题!
一开始一直以为是区间dp.. /* f下面必须有一个s 其余的s可以和任意f进行匹配 所以用线性dp来做 先预处理一下: fffssfsfs==>3 0 1 1 dp[i][j] 表示第i行缩进 ...
随机推荐
- R之内存管理
引言 R的内存管理机制究竟是什么样子的?最近几日在讲一个分享会,被同学问到这方面的问题,可是到网上去查,终于找到一篇R语言内存管理不过讲的不清不楚的,就拿memory.limit()函数来说,是在wi ...
- JFreeChart DateAxis用法
http://blog.csdn.net/xiaozhendong123/article/details/50131513
- linux及安全《Linux内核设计与实现》第三章——20135227黄晓妍
第三章 (由于linux不区分进程和线程,所以它们在linux中被称为task,也叫任务) 总结:本章主要包括进程以及线程的概念和定义,Linux内核如何管理每个进程,他们在内核中如何被列举,如何创建 ...
- 辅助模块应用(auxiliary/scanner/portscan/tcp)
实验步骤 创建msf所需的数据库 之前我们开启msf时下面总会出现一个红色的小减号,原来是因为没有和数据库键连接,于是首先我们要手动建立一个数据库... 使用命令来实现: service postgr ...
- Tomcat 发布项目 conf/Catalina/localhost 配置 及数据源配置
本文介绍通过在tomcat的conf/Catalina/localhost目录下添加配置文件,来发布项目.因为这样对 tomcat 的入侵性最小,只需要新增一个配置文件,不需要修改原有配置:而且支持动 ...
- SQL 触发器的缺点 坏处 弊端 哼╭(╯^╰)╮
(自己总结,有误请不吝赐教) 1.如果触发频率高,占用内存,降低数据访问速度 2.相对不灵活,一旦触发马上执行,不能排除特殊情况 3.一定程度上打乱代码结构,相关的代码都需要特别注释,否则造成阅读和维 ...
- requestWindowFeature()的应用
android开发中经常会在setContentView(R.layout.XXX); 前设置requestWindowFeature(XXXX). 他的意思是需要软件全屏显示.自定义标题(使用按钮等 ...
- Facade(外观)
意图: 为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 适用性: 当你要为一个复杂子系统提供一个简单接口时.子系统往往因为不断演化而变 ...
- spark streaming 使用geoIP解析IP
1.首先将GEOIP放到服务器上,如,/opt/db/geo/GeoLite2-City.mmdb 2.新建scala sbt工程,测试是否可以顺利解析 import java.io.Fileimpo ...
- c++ 中的 set
set (集合) 中的元素是排序好的,而且是不重复的. 例题:hdu 4989 题目大意:求一组数列中任意两个不重复元素和,再求不重复和的和. #include <bits/stdc++.h&g ...