目录
HDU1082——Matrix Chain Multiplication
HDU1080——Human Gene Functions
题目描述
运行代码
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
char a[110];
char b[110];
int dp[110][110];
int maxx(int a, int b, int c) {
int aa = -9999999;
if (a > aa)
aa = a;
if (b > aa)
aa = b;
if (c > aa)
aa = c;
return aa;
}
int ans[5][5] = {
{5, -1, -2, -1, -3},
{-1, 5, -3, -2, -4},
{-2, -3, 5, -2, -2},
{-1, -2, -2, 5, -1},
{-3, -4, -2, -1, 100000}
};
int find(char a) {
if (a == 'A')
return 0;
if (a == 'C')
return 1;
if (a == 'G')
return 2;
if (a == 'T')
return 3;
if (a == '-')
return 4;
}
int main() {
int t, n1, n2, n;
cin >> t;
while (t--) {
cin >> n1;
for (int i = 1; i <= n1; i++) {
cin >> a[i];
}
cin >> n2;
for (int i = 1; i <= n2; i++) {
cin >> b[i];
}
n = max(n1, n2);
//memset(dp, 0, sizeof(dp));
dp[0][0] = 0;
//cout << "&&" << ans[find('-')][find(a[2])] << endl;
for (int i = 1; i <= n; i++) {
dp[0][i] = dp[0][i - 1] + ans[find('-')][find(b[i])];
dp[i][0] = dp[i - 1][0] + ans[find(a[i])][find('-')];
}
for (int i = 1; i <= n1; i++) {
for (int j = 1; j <= n2; j++) {
dp[i][j] = maxx(dp[i - 1][j - 1] + ans[find(a[i])][find(b[j])], dp[i - 1][j] + ans[find(a[i])][find('-')], dp[i][j - 1] + ans[find('-')][find(b[j])]);
}
}
cout << dp[n1][n2] << endl;
}
return 0;
}
代码思路
-
首先定义了一些全局变量:
a
和b
两个字符数组用于存储输入的两个字符串。dp
二维数组用于动态规划过程中的值存储。ans
二维数组用于表示不同字符匹配的得分。
-
maxx
函数用于找出三个整数中的最大值。 -
find
函数根据输入的字符,返回其对应的索引,用于在ans
数组中查找匹配得分。 -
在
main
函数中:- 首先读取测试用例的数量
t
。 - 对于每个测试用例:读取两个字符串的长度
n1
和n2
,并分别读取这两个字符串的字符。找到两个长度中的最大值n
。初始化dp[0][0]
为 0 ,并通过循环初始化dp
数组的第一行和第一列。通过两层循环,计算dp
数组中其他位置的值,其值为三种可能情况(左上角斜对角的值加上当前字符匹配得分、上方的值加上当前字符与-
的匹配得分、左方的值加上当前字符与-
的匹配得分)的最大值。最后输出dp[n1][n2]
,即两个字符串匹配的最大得分。
- 首先读取测试用例的数量
HDU1081——To The Max
题目描述
运行代码
#include <iostream>
#define MAX 101
using namespace std;
#include<stdio.h>
#include<math.h>
#include<algorithm>
int map[MAX][MAX];
int main() {
int n, i, j, k;
while (scanf_s("%d", &n) != EOF) {
memset(map, 0, sizeof(map));
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
scanf_s("%d", &map[i][j]);
map[i][j] += map[i][j - 1];
}
}
int maxSum = INT_MIN;
for (i = 1; i <= n; i++) {
for (j = i; j <= n; j++) {
int curSum = 0;
for (k = 1; k <= n; k++) {
curSum = max(0, curSum) + (map[k][j] - map[k][i - 1]);
maxSum = max(maxSum, curSum);
}
}
}
printf("%d\n", maxSum);
}
return 0;
}
代码思路
-
首先定义了一个二维数组
map
用于存储输入的数据,以及一些变量n
、i
、j
、k
等。 -
在输入部分,通过
scanf_s
函数获取矩阵的大小n
。然后使用两层循环,将输入的数据存储到map
数组中,并计算每行的前缀和,即map[i][j] += map[i][j - 1]
,这样方便后续计算某一列区间的和。 -
接下来是计算最大子矩阵和的部分。
- 外层两层循环
for (i = 1; i <= n; i++)
和for (j = i; j <= n; j++)
用于确定子矩阵的列的范围,从第i
列到第j
列。 - 内层循环
for (k = 1; k <= n; k++)
用于遍历每一行。 - 在每次内层循环中,计算当前子矩阵(从第
i
列到第j
列,第k
行)的和,并通过与当前的和curSum
相加更新curSum
。如果curSum
小于 0 ,则将其重置为 0 ,然后更新最大和maxSum
。
- 外层两层循环
-
最后输出最大子矩阵的和。
HDU1082——Matrix Chain Multiplication
题目描述
运行代码
#include<iostream>
#include<map>
#include<stack>
#include<string>
using namespace std;
struct m {
int a;
int b;
};
map<char, m>mat;
int main() {
int n;
cin >> n;
while (n--) {
char c;
cin >> c;
cin >> mat[c].a >> mat[c].b;
}
string s;
while (cin >> s) {
stack<m>k;
int sum = 0;
bool f = false;
for (char t : s) {
if (t == '(')continue;
if (t == ')'){
m t1=k.top();
k.pop();
m t2 = k.top();
k.pop();
if (t2.b != t1.a) {
f = true;
break;
}
sum += t2.a * t2.b * t1.b;
t2.b = t1.b;
k.push(t2);
}
else {
k.push(mat[t]);
}
}
if(f) cout << "error" << endl;
else cout << sum << endl;
}
}
代码思路
-
首先定义了一个结构体
m
来表示矩阵的行和列。 -
使用一个
map
来存储不同字符代表的矩阵的行和列信息。 -
在
main
函数中:- 首先读取矩阵的数量
n
,然后通过循环读取每个矩阵的字符标识以及行和列的大小,并存入mat
中。 - 接下来读取表达式字符串
s
。 - 使用一个栈
k
来存储矩阵信息。 - 遍历表达式字符串:
- 遇到
(
时跳过。 - 遇到
)
时,取出栈顶的两个矩阵,检查它们是否能相乘(列数和行数是否匹配)。如果不匹配,设置错误标志f
为true
并退出。如果匹配,计算乘法的运算量并更新栈顶矩阵的列信息,将结果累加到总和sum
中。 - 遇到字符时,从
mat
中取出对应的矩阵信息并压入栈中。
- 遇到
- 根据错误标志
f
输出结果,如果没有错误则输出乘法运算的总和,否则输出 "error" 。
- 首先读取矩阵的数量