NKUSOFT 算法导论上机作业3

最长公共子序列

总提交数: 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]; // 返回最大价值
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值