【动态规划基础篇】【矩阵取数/最大字段和/最长公共子序列(LCS)/编辑距离/最长上升子序列(LIS)】
2016-05-22 13:47
549 查看
矩阵取数问题
题目链接:http://www.51nod.com/tutorial/course.html#!courseId=1
题目描述
一个N*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,从左上走到右下,只能向下向右走,求能够获得的最大价值。
输入
第1行:N,N为矩阵的大小。(2 <= N <= 500)第2 - N + 1行:每行N个数,中间用空格隔开,对应格子中奖励的价值。(1 <= N[i] <= 10000)
输出
输出能够获得的最大价值。
输入示例
31 3 3
2 1 3
2 2 1
输出示例
11AC代码:
// dp矩阵取数问题; #include<iostream> #include<cstdio> #include<cstring> using namespace std; int main() { int a[505][505]; int dp[505][505]; // 到x,y点的最大奖励; int n; cin.sync_with_stdio(false); cin>>n; for(int i=0;i<n;i++) for(int j=0;j<n;j++) cin>>a[i][j]; memset(dp,0,sizeof(dp)); dp[0][0]=a[0][0]; for(int i=1;i<n;i++) dp[0][i]=dp[0][i-1]+a[0][i]; for(int i=1;i<n;i++) dp[i][0]=dp[i-1][0]+a[i][0]; for(int i=1;i<n;i++){ for(int j=1;j<n;j++){ dp[i][j]=max(dp[i-1][j],dp[i][j-1])+a[i][j]; } } cout<<dp[n-1][n-1]<<endl; return 0; }
最大子段和问题
题目链接:http://www.51nod.com/tutorial/course.html#!courseId=2题目描述
输入
N个整数组成的序列a[1],a[2],a[3],…,a
,求该序列如a[i]+a[i+1]+…+a[j]的连续子段和的最大值。当所给的整数均为负数时和为0
输入
第1行:整数序列的长度N(2 <= N <= 50000) 第2 - N + 1行:N个整数(-10^9 <= A[i] <= 10^9)
输出
输出最大子段和。
输入示例
6 -2 11 -4 13 -5 -2
输出示例
20
AC代码:
// 最大子段和#include<iostream>
#include<cstring>
#define LL long long
using namespace std;
int main()
{
int n;
int a[51010];
cin.sync_with_stdio(false);
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
LL maxSum=0;
LL ans=0;
int s=0,ss=0,ee=0; // 分别表示起始和终止位置;
for(int i=0;i<n;i++){
if(maxSum>0){ // 大于,就可以一直加;
maxSum+=a[i];
}else{
s=i; // 标记起始位置
maxSum=a[i]; // 重新开始;
}
if(maxSum>ans){ // 判断是否能够更新ans;
ans=maxSum;
ss=s;
ee=i;
}
}
//cout<<ss<<' '<<ee<<endl; //分别记录起始位置和终止位置;
cout<<ans<<endl;
return 0;
}
最长公共子序列问题
题目链接:http://www.51nod.com/tutorial/course.html#!courseId=4
题目描述
给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的)。
输入
第1行:字符串A 第2行:字符串B (A,B的长度 <= 1000)
输出
输出最长的子序列,如果有多个,随意输出1个。
输入示例
abcicba abdkscab
输出示例
abca
AC代码:
//最长公共子序列 //记录序列; #include<iostream> using namespace std; int dp[1010][1010]={0}; int s[1010][1010]={0}; // 记录结果; string s1,s2; void print(int i,int j) { if(i==0||j==0) return; if(s[i][j]==0){ // 相同情况; print(i-1,j-1); cout<<s1[i]; } else if(s[i][j]==1) print(i-1,j); else print(i,j-1); } int main() { cin.sync_with_stdio(false); cin>>s1>>s2; s1="#"+s1; s2="@"+s2; int len1=s1.size(); int len2=s2.size(); for(int i=0;i<len1;i++){ for(int j=0;j<len2;j++){ if(i==0||j==0){ dp[i][j]=0; s[i][j]=0; }else{ if(s1[i]==s2[j]){ dp[i][j]=dp[i-1][j-1]+1; s[i][j]=0; }else{ if(dp[i-1][j]>=dp[i][j-1]){ dp[i][j]=dp[i-1][j]; s[i][j]=1; }else{ dp[i][j]=dp[i][j-1]; s[i][j]=-1; } } } } } print(len1-1,len2-1); //cout<<dp[len1-1][len2-1]<<endl; //cout<<s[len1-1][len2-1]<<endl; return 0; }
编辑距离问题
题目链接:http://www.51nod.com/tutorial/course.html#!courseId=3题目描述
编辑距离,又称Levenshtein距离(也叫做Edit Distance),是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。
例如将kitten一字转成sitting:
sitten (k->s)
sittin (e->i)
sitting (->g)
所以kitten和sitting的编辑距离是3。俄罗斯科学家Vladimir Levenshtein在1965年提出这个概念。
给出两个字符串a,b,求a和b的编辑距离。
输入
第1行:字符串a(a的长度 <= 1000)。 第2行:字符串b(b的长度 <= 1000)。
输出
输出a和b的编辑距离
输入示例
kitten sitting
输出示例
3
AC代码:
// 编辑距离; #include<iostream> #include<cstring> using namespace std; int len1,len2; string s1,s2; int dp[1005][1005]; void init() { s1="#"+s1; s2="@"+s2; len1=s1.size(); len2=s2.size(); for(int i=0;i<len1;i++) dp[i][0]=i; for(int i=0;i<len2;i++) dp[0][i]=i; } int main() { cin.sync_with_stdio(false); cin>>s1>>s2; init(); for(int i=1;i<len1;i++){ for(int j=1;j<len2;j++){ dp[i][j]=min(min(dp[i-1][j]+1,dp[i][j-1]+1),dp[i-1][j-1]+((s1[i]==s2[j])?0:1)); //cout<<dp[i][j]<<endl; } } cout<<dp[len1-1][len2-1]<<endl; return 0; }
相关文章推荐
- 学习SpringMVC(十四)之关于重定向
- adb shell
- NYoj_49开心的小明
- 类的继承
- jsp之间传输中文乱码问题的解决办法
- JavaScript数组合并的多种方法
- 3.1 mysql客户端工具
- Activity class {package/class} does not exist及Unable to start activity ComponentInfo 解决方法
- Hibernate的SqlNode cannot be PathNode异常
- linux常用指令
- Swift新浪微博
- [开源]基于STM32的录音播放装置
- 在ZedBoard开发板上部署Node.js(v6.2.0)服务
- Linux下tar命令的简单使用
- 摩托车继承自行车和机动车
- 浅析JavaScript回调函数应用
- MY_GEEK_2D动画切换
- 第102讲: 动手实战Spark Streaming自定义Receiver并进行调试和测试
- IEEE 754标准
- 教师兼干部类