最长公共子序列
总提交数: 910次通过数: 432次通过率: 47.47%
内存限制: 104857600(BYTE)时间限制: 1000(MS)输入限制: 1000(行)输出限制: 1000(行)
题目描述
给出字符串str1和str2,如果一个字符串s同是str1和str2的子序列,则称s为二者的公共子序列,如果s最长,则称s为最长公共子序列,即LCS.
尝试使用动态规划的方法找出给定字符串的最长公共子序列长度.
输入的第一行为字符串str1.
输入的第二行为字符串str2.
样例输入输出
样例1
输入:
abcde
ace
输出:
3
样例2
输入:
qwe
dfg
输出:
0
#include<iostream>
using namespace std;
int LcsLength(string str1, string str2);
int main() {
string str1, str2;
cin >> str1 >> str2;
cout << LcsLength(str1, str2);
}
int LcsLength(string str1, string str2) {
int** dp = new int*[str1.length()+1];
for (int i = 0; i < str1.length()+1; i++) {
dp[i] = new int[str2.length()+1];
if (i == 0) {
for (int j = 0; j < str2.length()+1; j++) {
dp[i][j] = 0;
}
}
dp[i][0] = 0;
}
for (int i = 1; i < str1.length()+1; i++) {
for (int j = 1; j < str2.length()+1; j++) {
if (str1[i - 1] == str2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
}
else {
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
return dp[str1.length()][str2.length()];
}
01背包问题
总提交数: 789次通过数: 314次通过率: 39.80%
内存限制: 104857600(BYTE)时间限制: 1000(MS)输入限制: 1000(行)输出限制: 1000(行)
题目描述
现在有一个容量为v的背包和n件体积不同价值不同的物品,应该如何选择装入物品使背包中的物品总价值最大.
要求使用动态规划的思维计算出背包能装下的最大物品总价值.
输入第一行为两个整数,n和v,n表示总的物品数量,v表示背包的容量.
接下来的n行每行包括两个整数,分别表示物品的体积和价值.
提示:
对于40%的数据,n≤10;
对于100%的数据,n≤50.
样例输入输出
样例1
输入:
5 20
5 3
7 4
8 2
6 1
3 8
输出:
15
样例2
输入:
5 50
25 15
16 9
2 3
8 8
6 4
输出:
32
#include<iostream>
using namespace std;
//注意 这是一个0-1背包问题 物品只能拿一个或者不拿
class KnapsackProblem
{
public:
int n;//有n种物品
int b;//背包最大重量限制
int** item;//二维数组 存放每种物品的重量item[i][0]和价值item[i][1]
KnapsackProblem(int inputn, int inputb, int** inputitem) {
n = inputn;
b = inputb;
item = inputitem;
}
int Solution1(int k, int y);
int Solution2(int y);
};
int main() {
int n , b ;
cin >> n >> b ;
int** item = new int* [n];
for (int i = 0; i < n; i++) {
item[i] = new int[2];
cin >> item[i][0] >> item[i][1];
}
KnapsackProblem kp (n, b, item);
//cout << kp.Solution1(n, b) << endl;//Solution1采用递归实现 速度较慢
cout << kp.Solution2(b);//Solution2采用动态规划实现 速度较快
}
int KnapsackProblem::Solution1(int k, int y) {//F(k,y)=只允许装前k种物品,背包总重不超过y时背包最大的价值
if (k == 0)return 0;//0<=k<=n
if (y == 0)return 0;//0<=y<=b
if (k == 1)return (y >= item[0][0]) ? item[0][1] : 0; //(y >= item[0][0]) ? (y / item[0][0]) * item[0][1] : 0;
if (y < 0)return -99999;
int value = max(Solution1(k - 1, y), Solution1(k-1,y-item[k-1][0])+item[k-1][1]);
return value;
}
int KnapsackProblem::Solution2(int y) {
int** dp = new int* [n + 1];// 动态规划二维数组dp[n+1][y+1],dp[i][j]表示前i种物品总重量不超过j时的最大价值
for (int i = 0; i < n + 1; i++) {
dp[i] = new int[y + 1];
}
// 初始化dp数组第一行和第一列
for (int i = 0; i <= n; i++)
dp[i][0] = 0;
for (int j = 0; j <= y; j++)
dp[0][j] = 0;
// 动态规划计算过程
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= y; j++) {
if (item[i - 1][0] > j) {
dp[i][j] = dp[i - 1][j]; // 物品i无法放入背包
}
else {
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - item[i - 1][0]] + item[i - 1][1]); // 物品i可以放入背包或者不放入背包
}
}
}
return dp[n][y]; // 返回最大价值
}