数字三角形
从顶层走到最底层,每一步可以选择走左下角或者右下角,选择一条路径上数字和最大的路径
- 状态表示
- 集合:所有从起点,走到(i,j)的路径
- 属性:Max
- 状态计算
let buf=''
process.stdin.on('readable',function(){
let chunk = process.stdin.read();
if(chunk) buf+=chunk.toString();
})
process.stdin.on('end',function(){
//处理输入三角形
let inputs=buf.split('\n');
let n=parseInt(inputs.shift());
let a = [];
for(let i=0;i<=n;i++){
a[i]=new Array(i);
}
a[1][1]=parseInt(inputs.shift());
for(let i=2;i<=n;i++){
let line=inputs.shift().split(" ")
for(let j=1;j<=i;j++){
a[i][j]=parseInt(line.shift());
}
}
//初始化DP
let f=[]
for(let i=0;i<=n;i++){
f[i]=new Array(i+2).fill(-Infinity);
}
f[1][1]=a[1][1];
for(let i=2;i<=n;i++){
for(j=1;j<=i;j++){
f[i][j]=Math.max(f[i-1][j-1]+a[i][j],f[i-1][j]+a[i][j]);
}
}
let res = -Infinity;
for(let i=1;i<=n;i++){
res = Math.max(res,f[n][i]);
}
console.log(res)
})
最长上升子序列
找到给定整数数组中最长严格递增子序列的长度
- 状态表示
- 集合: 所有以第i个数结尾的上升子序列
- 属性: max
- 状态计算
var lengthOfLIS = function(nums) {
const len = nums.length;
if(!len) return 0;
let maxLen = 1;
let dp = new Array(len).fill(1)
for(let i=1;i<len;i++){
for(let j=0;j<i;j++){
//如果发现比当前元素小的元素,则为可以延长的上升子序列,更新状态
if(nums[j]<nums[i]){
dp[i]=Math.max(dp[i],dp[j]+1);
}
}
//更新最大值
if(dp[i]>maxLen) maxLen=dp[i];
}
return maxLen;
};
最长公共子序列
给定两个字符串 返回这两个字符串的最长公共子序列的长度
- 状态表示f[i][j]
- 集合:所有a[1-i]、b[1-j]的公共子序列的集合
- 属性: max
- 状态计算
00对应的a[i]和b[i]都不包含的情况其实在01或者10种都有可能出现,重复了所以不用划分这种情况,只有三种情况。
var longestCommonSubsequence = function(text1, text2) {
let n=text1.length;
let m=text2.length;
let arr1=new Array(0,...text1);
let arr2=new Array(0,...text2);
let f=[];
for(let i=0;i<=n;i++){
f[i] = new Int32Array(m+1);
}
for(let i=1;i<=n;i++){
for(let j=1;j<=m;j++){
f[i][j] = Math.max(f[i-1][j],f[i][j-1]);
if(arr1[i]===arr2[j]) f[i][j]= Math.max(f[i][j],f[i-1][j-1]+1);
}
}
return f[n][m];
};
最短编辑距离
字符串1转换成字符串需要的最少的操作步骤数 操作:增1字符 删1字符 改1个字符
- 状态表示
- 集合:将a[i-i]转换成b[1-j]的所有操作方式
- 属性:最少的步骤 min
- 状态计算
最后一种情况,如果a[i]和b[j]不相等 需要一步;相等就不需要修改
let buf = "";
process.stdin.on('readable',function(){
let chunk = process.stdin.read();
if(chunk) buf+=chunk.toString();
})
process.stdin.on('end',function(){
const lines = buf.split("\n");
const n = parseInt(lines[0]);
const m=parseInt(lines[2])
const a=new Array(0,...lines[1]);
const b=new Array(0,...lines[3]);
let f=[];
for(let i=0;i<=n;i++){
f[i]=new Int32Array(m+1);
}
for(let i=1;i<=n;i++) f[i][0]=i;
for(let i =1;i<=m;i++) f[0][i]=i;
for(let i=1;i<=n;i++){
for(let j=1;j<=m;j++){
f[i][j]=Math.min(f[i-1][j]+1,f[i][j-1]+1);
if(a[i]===b[j]){
f[i][j]=Math.min(f[i][j],f[i-1][j-1]);
}else{
f[i][j]=Math.min(f[i][j],f[i-1][j-1]+1);
}
}
}
console.log(f[n][m])
})