目录
Acwing 898. 数字三角形
输入样例:
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
思路分析:
代码展示:
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 510, INF = 0x3f3f3f3f;
int a[N][N], f[N][N];
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= i; j ++ )
cin >> a[i][j];
memset(f, -INF, sizeof f);
f[1][1] = a[1][1];
for (int i = 2; i <= n; i ++ )
{
for (int j = 1; j <= i; j ++ )
{
f[i][j] = max(f[i - 1][j - 1] + a[i][j], f[i - 1][j] + a[i][j]);
}
}
int res = -INF;
for (int i = 1; i <= n; i ++ ) res = max(res, f[n][i]);
cout << res << endl;
return 0;
}
Acwing 895. 最长上升子序列
输入样例:
7
3 1 2 1 8 5 6
思路分析:
代码展示:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
int f[N], a[N];
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i ++ ) cin >> a[i];
for (int i = 1; i <= n; i ++ )
{
f[i] = 1;
for (int j = 1; j < i; j ++ )
{
if (a[i] > a[j]) f[i] = max(f[i], f[j] + 1);
}
}
int res = 0;
for (int i = 1; i <= n; i ++ ) res = max(res, f[i]);
cout << res << endl;
return 0;
}
Acwing 896. 最长上升子序列 II
思路分析:
模拟样例更新过程:
代码展示:
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 101000, INF = 0x3f3f3f3f;
int n;
int a[N], q[N];
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i ++) scanf("%d", &a[i]);
int len = 0;
q[0] = -INF; //q[0]存储长度为零的最小的数,这里的目的是起哨兵作用
//枚举每一个数
for (int i = 1; i <= n; i ++)
{
//从q[]用二分查找出小于a[i]的最大的数
int l = 0, r = len;
while (l < r)
{
int mid = (l + r + 1) / 2;
if (a[i] > q[mid]) l = mid;
else r = mid - 1;
}
len = max(len, r + 1);
q[r + 1] = a[i];
}
printf("%d\n", len);
return 0;
}
Acwing 897. 最长公共子序列
输入样例:
4 5
acbd
abedc
思路分析:
代码展示:
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1010;
char a[N], b[N];
int f[N][N];
int main()
{
int n, m;
scanf("%d%d", &n, &m);
scanf("%s%s", a + 1, b + 1);
for (int i = 1; i <= n; i ++ )
{
for (int j = 1; j <= m; j ++ )
{
f[i][j] = max(f[i - 1][j], f[i][j - 1]);
if (a[i] == b[j]) f[i][j] = max(f[i][j], f[i - 1][j - 1] + 1);
}
}
printf("%d\n", f[n][m]);
return 0;
}
Acwing 902. 最短编辑距离
输入样例:
10
AGTCTGACGC
11
AGTAAGTAGGC
思路分析:
代码展示:
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1010;
char a[N], b[N];
int f[N][N];
int main()
{
int n, m;
scanf("%d%s", &n, a + 1);
scanf("%d%s", &m, b + 1);
for (int i = 1; i <= m; i ++ ) f[0][i] = i;
for (int i = 1; i <= n; i ++ ) f[i][0] = i;
for (int i = 1; i <= n; i ++ )
{
for (int j = 1; j <= m; j ++ )
{
f[i][j] = min(f[i - 1][j] + 1, f[i][j - 1] + 1);
if (a[i] != b[j]) f[i][j] = min(f[i][j], f[i - 1][j - 1] + 1);
else f[i][j] = min(f[i][j], f[i - 1][j - 1]);
}
}
printf("%d\n", f[n][m]);
return 0;
}
Acwing 899. 编辑距离
思路分析:
大体思路同上一道最短编辑距离,只不过加了限制条件
代码展示:
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 1010;
int n, m;
char s[N][N];
int f[N][N];
int check(char a[], char b[])
{
int la = strlen(a + 1), lb = strlen(b + 1);
for (int i = 0; i <= la; i ++) f[i][0] = i;
for (int i = 0; i <= lb; i ++) f[0][i] = i;
for (int i = 1; i <= la; i ++)
{
for (int j = 1; j <= lb; j ++)
{
f[i][j] = min(f[i - 1][j] + 1, f[i][j - 1] + 1);
if (a[i] != b[j]) f[i][j] = min(f[i][j], f[i - 1][j - 1] + 1);
else f[i][j] = min(f[i][j], f[i - 1][j - 1]);
}
}
return f[la][lb];
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i ++)
cin >> s[i] + 1;
while (m --)
{
char p[N];
int limit;
cin >> p + 1 >> limit;
int res = 0;
for (int i = 1; i <= n; i ++)
if (check(s[i], p) <= limit)
res ++;
cout << res << endl;
}
return 0;
}