最长递增子序列 编辑距离问题 青蛙过桥 寻宝路线 回文串问题 租用游艇问题 数字三角形 至多删三个字符
最长递增子序列 编辑距离问题 青蛙过桥 寻宝路线 回文串问题 租用游艇问题 数字三角形 至多删三个字符
/*弗洛伊德算法(三重循环,中间变量, 起始点, 重点循环顺序) */
1.最长递增子序列:o(N^2)
a[], len1 = strlen(a) b[] = {1} 记录I点的最长递增序列; for(i = 1; i < len1; i++) { for(j = 0; j < i; j++) { if(a[i] > a[j] && b[i] < b[j]+1)//b[i] 等于(所有小于的数的最长子序列的长度)+ 1 { b[i] = b[j] + 1; } } }
2 编辑距离问题 (30 分)
设A和B是2个字符串。要用最少的字符操作将字符串A转换为字符串B。
这里所说的字符操作包括 (1)删除一个字符; (2)插入一个字符; (3)将一个字符改为另一个字符。
将字符串A变换为字符串B所用的最少字符操作数称为字符串A到 B的编辑距离,记为d(A,B)。 对于给定的字符串A和字符串B,计算其编辑距离 d(A,B)。
dd[i][j]//a串0-i变到b串的0-j的最短编辑问题; for(i = 0; i <= len1; i++)//某一个串到了0,能一个串剩下的都要删掉,所以编辑距离为i; { dd[0][i] = i; dd[i][0] = i; } for(i = 1; i <= len1; i++) { for(j = 1; j <= len2; j++) { if(a[i] == b[j]) t = 0; else t = 1; dd[i][j] = min(dd[i-1][j]+1, dd[i][j-1]+1, dd[i-1][j-1] + t);// min 找出三个数最小的值,三个值分别是插入一个, 删一个, //改变一个; } } cout<<dd[len1][len2];
3 青蛙过桥 (25 分)
一座长度为n的桥,起点的一端坐标为0,且在整数坐标i处有a[i]个石头【0<=a[i]<=4】,
一只青蛙从坐标0处开始起跳,一步可以跳的距离为1或2或3【即每一步都会落在整数点处】,
青蛙落在i处会踩着该点的所有石头,求青蛙跳出这座桥最少踩多少个石头?并且输出依次跳
过的坐标点路线,如果存在多种路线,输出字典序最小的那一条。
输入格式:
第一行整数n(<150000),接着下一行会有n+1个由空格隔开的整数,即桥上各个坐标处石头数量。
输出格式:
第一行为踩着最少石头个数,第二行为依次跳过的坐标点【字典序最小的】。
输入样例:
在这里给出两组输入。例如:
10
1 2 1 3 0 3 1 2 1 1 2
100
1 2 0 4 0 1 3 4 2 2 1 3 1 4 0 3 0 1 2 3 3 2 2 0 1 0 0 0 0 1 2 1 3 4 0 3 4 4 1 0
4 1 3 1 1 2 3 4 4 4 0 2 0 1 1 1 3 1 3 2 1 2 4 1 2 1 4 1 0 0 1 2 3 0 2 4 4 0 0 4
2 0 0 2 1 3 3 3 0 0 2 0 0 1 2 4 2 2 2 4 0
void ff(int n)// 这个函数作用就是自底向上递推求踩点数最少;
{
int t, j, i;
for(i = n; i >= 1; i–)
{
t = Max(c[1], c[2], c[3]);
j = c[t];
c[3] = c[2]; c[2] = c[1]; c[1] = j + a[i]; b[i] = c[1]; }
}
void fff(int n, int k)// n 代表桥的总数, K代表当前在那个点上; //此函数的作用是负责输入路线, { int t; if(n - 3 >= k) { if(k == 1) cout<<k-1; else cout<<" "<<k-1; t = Max(b[k+1], b[k+2], b[k+3]);//max 函数就是求三个数最大值, fff(n, k+t); } else { cout<<" "<<k-1; } }
4 寻宝路线 (40 分)
在一个m行n列方格矩阵中,每一个方格内摆放着价值不等的宝贝(价值可正可负)
,让小明感到好奇的是,从左上角到达右下角的所有可能路线中,能捡到宝贝的价值总和最大是多少?
而且这种达到最大值的路线 又有多少条?【注意:只能从一个格子向下或向右走到相邻格子,并且走到的格子宝贝一定会被捡起。】
输入格式:
第一行为整数m,n(均不大于100),下一行开始会有一个m行n列的整数方阵,对应方格矩阵中的宝贝价值(这些值的绝对值都不超过500)。
输出格式:
单独一行输出2个整数,分别为能捡到宝贝价值总和的最大值和达到最大值的路线数量,2个整数间隔一个空格。
输入样例:
在这里给出一组输入。例如:
4 5
2 -1 6 -2 9
-3 2 5 -5 1
5 8 3 -2 4
5 2 8 -4 7
可能看着比较复杂,只是条件控制语句没有优化;
void fff(int x, int y, int n, int m)// m, n 很显然是问题的规模,x, y是当前的在的左边,都是从坐标1,1 开始的 { if(x > 0 && x <= n && y > 0 && y <= m) { if(x == n && y == m) { } else { if(x + 1 > n) { if(y +1 > n) { } else fff(x, y+1, n, m); } else { if(y+1 > n) fff(x+1, y, n, m); else { if(b[x][y+1] == b[x+1][y]) { z++; fff(x, y+1, n, m); fff(x+1, y, n, m); } else { if(b[x+1][y] > b[x][y+1]) fff(x+1, y, n, m); else fff(x, y+1, n, m); } } } } } }
5 回文串问题 (25 分)
一个字符串,如果从左到右读和从右到左读是完全一样的,比如"aba",我们称其为回文串。
现在给你一个字符串,可在任意位置添加字符,求最少添加几个字符,才能使其变成一个回文串。
输入格式:
任意给定的一个字符串,其长度不超过1000.
输出格式:
能变成回文串所需添加的最少字符数。
输入样例:
在这里给出一组输入。例如:
Ab3bd
Abb
# include<iostream> # include<cstring> using namespace std; int d[1001][1001];//都初始化为-1; int ff(string a, int x, int y)//x, y分别代表起点和终点,此程序是从首尾两端同时向中间推的; { int i, j; if(x <= y) { if(a[x] == a[y])//首尾相等进行下一个, { if(d[x+1][y-1] != -1) { d[x][y] = d[x+1][y-1]; return d[x][y]; } else { d[x][y] = ff(a, x+1, y-1); return d[x][y]; } } else//不相等,左添加一个,或右边添加一个; { if(d[x+1][y] != -1) i = d[x+1][y] + 1; else i = ff(a, x+1, y) + 1; if(d[x][y-1] != -1) j = d[x][y-1] + 1; else j = ff(a, x, y-1) + 1; d[x][y] = i > j ? j : i; return d[x][y]; } } else return 0; } int main() { int i, j; string a; cin>>a; for(i = 0; i <= 1000; i++) memset(d[i], -1, 4*1000); int len = a.size(); cout<<ff(a, 0, len-1); return 0; }
6 租用游艇问题 (15 分)
题目来源:王晓东,《算法设计与分析》
长江游艇俱乐部在长江上设置了n个游艇出租站1,2,…,n。游客可在这些游艇出租站租用游艇,
并在下游的任何一个游艇出租站归还游艇。游艇出租站i到游艇出租站j之间的租金为r(i,j),1<=i<j<=n。
试设计一个算法,计算出从游艇出租站1 到游艇出租站n所需的最少租金。
输入格式:
第1 行中有1 个正整数n(n<=200),表示有n个游艇出租站。接下来的第1到第n-1 行,第i行表示第i站到第i+1站,第i+2站, … , 第n站的租金。
输出格式:
输出从游艇出租站1 到游艇出租站n所需的最少租金。
输入样例:
在这里给出一组输入。例如:
3
5 15
7
输出样例:
在这里给出相应的输出。例如:
12
//实际上是用的回溯算法;
# include
using namespace std; int a[200][200]; int max1 = 100000000; int num = 0; void ff(int n, int k) { int i; if(k <= n) { for(i = k+1; i <= n; i++) { num += a[k][i]; ff(n, i); num -= a[k][i]; } } if(k == n) { if(num < max1) max1 = num; } } int main() { int i, j, n; scanf("%d", &n); for(i = 1; i < n; i++) { for(j = i+1; j <= n; j++) scanf("%d", &a[i][j]); } ff(n, 1); printf("%d", max1); return 0; }
7 数字三角形 (30 分)
给定一个由 n行数字组成的数字三角形如下图所示。试设计一个算法,
计算出从三角形 的顶至底的一条路径(每一步可沿左斜线向下或右斜线向下),使该路径经过的数字总和最大。
输入格式:
输入有n+1行:
第 1 行是数字三角形的行数 n,1<=n<=100。
接下来 n行是数字三角形各行中的数字。所有数字在0…99 之间。
输出格式:
输出最大路径的值。
输入样例:
在这里给出一组输入。例如:
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
输出样例:
在这里给出相应的输出。例如:
30
//循环性写法,C
# include<stdio.h> int a[105][105]; int b[105][105]; int max(int a, int b) { return a > b ? a : b; } int main() { int i, j; int n; scanf("%d", &n); for(i = 1; i <= n; i++) { for(j = 1; j <= i; j++) scanf("%d", &a[i][j]); } for(i = 1; i <= n; i++) b [i] = a [i]; for(i = n-1; i >= 1; i--) { for(j = 1; j <= i; j++) { b[i][j] = max(b[i+1][j], b[i+1][j+1]) + a[i][j]; } } printf("%d", b[1][1]); return 0; }
8 至多删三个字符 (35 分)
给定一个全部由小写英文字母组成的字符串,允许你至多删掉其中 3 个字符,结果可能有多少种不同的字符串?
输入格式:
输入在一行中给出全部由小写英文字母组成的、长度在区间 [4, 10
?6
?? ] 内的字符串。
输出格式:
在一行中输出至多删掉其中 3 个字符后不同字符串的个数。
输入样例:
ababcc
输出样例:
25
提示:
删掉 0 个字符得到 “ababcc”。
删掉 1 个字符得到 “babcc”, “aabcc”, “abbcc”, “abacc” 和 “ababc”。
删掉 2 个字符得到 “abcc”, “bbcc”, “bacc”, “babc”, “aacc”, “aabc”, “abbc”, “abac” 和 “abab”。
删掉 3 个字符得到 “abc”, “bcc”, “acc”, “bbc”, “bac”, “bab”, “aac”, “aab”, “abb” 和 “aba”。
作者: 曹鹏
单位: Google
时间限制: 400 ms
内存限制: 64 MB
#include<bits/stdc++.h> #define N 1000002 typedef long long LL; char S ; LL F [4]; /*LL dp1(int i,int j)//由于i可达到100万,递归深度会超出 ,所以要写成循环型 { if(j<0||j>i) return 0; if(F[i][j]) return F[i][j]; if(j==0||j==i) return F[i][j]=1; else { int k,t=0; for(k=i-1;k>=i-j;k--) if(S[k]==S[i]) { t=f(k-1,j+k-i); break;} return F[i][j] = f(i-1,j)+f(i-1,j-1)-t; } } */ int main() { int n=1,i,j,k; scanf("%s",S+1); n=strlen(S+1); for(i=0;i<=n;i++) for(j=0;j<=3;j++) if(j==0||j==i) F[i][j]=1; else if(j<i) { F[i][j] = F[i-1][j]+F[i-1][j-1]; for(k=i-1;k>=i-j;k--) if(S[k]==S[i]) { F[i][j] -= F[k-1][j+k-i]; break; } } printf("%lld\n",F [0]+F [1]+F [2]+F [3]); return 0; }
- 动态规划问题学习路线:斐波那契数列,最大递增子序列,松鼠捡苹果,最大公共子序列,字符串编辑距离
- 找工作知识储备---数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 【动态规划】序列连配问题:编辑距离
- 最大子序列、最长递增子序列、最长公共子串、最长公共子序列、字符串编辑距离
- 最长上升子序列 最长公共子序列 最长公共子串 数字三角形 等简单DP以及变形
- 算法_动态规划_最长单调递增子序列问题(O(nlogn)的时间复杂度)
- 最长递增子序列问题(最大流)
- 数字三角问题与租用游艇问题
- 算法基础之python实现动态规划中数字三角形和最长上升子序列问题
- 编程实现:从字符中获取连续数组序列,如字符串"a1dl2iad9j3la5kudp7u9pn4blj8ap5u3e6ml9a"中可以得到的连续数字序列为1234556.【注】:只考虑一位,因此最长的数
- C语言实现最长递增子序列问题的解决方法
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 最大数字序列和问题,买卖股票问题,以及最长公共字串问题
- 动态规划——最大子序列、最长递增子序列、最长公共子串、最长公共子序列、字符串最小编辑距离日记整理
- 转:最大子序列、最长递增子序列、最长公共子串、最长公共子序列、字符串编辑距离
- 找工作知识储备(2)---数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- ACM最长单调递增子序列问题(动态规划)o(n*n)C++实现
- 最大子序列、最长递增子序列、最长公共子串、最长公共子序列、字符串编辑距离
- 最大子序列、最长递增子序列、最长公共子串、最长公共子序列、字符串编辑距离
- 最大子序列、最长递增子序列、最长公共子串、最长公共子序列、字符串编辑距离