10.19—动态规划 //最长公共子序列//防卫导弹//田忌赛马//计算矩阵连乘积//最长子序列的长度

1.最长公共子序列

描述:一个给定序列的子序列是在该序列中删去若干元素后得到的序列。确切地说,若给定序列X=<x1, x2,…, xm>,则另一序列Z=<z1, z2,…, zk>是X的子序列是指存在一个严格递增的下标序列 <i1, i2,…, ik>,使得对于所有j=1,2,…,k有:

Xij = Zj
如果一个序列S即是A的子序列又是B的子序列,则称S是A、B的公共子序列。
求A、B所有公共子序列中最长的序列的长度。

输入:输入共两行,每行一个由字母和数字组成的字符串,代表序列A、B。A、B的长度不超过200个字符。

输出:一个整数,表示最长各个子序列的长度。格式:printf("%d\n");

输入样例

programming
contest

输出样例

2

#include<iostream>
#include<string.h>
#include<math.h>
using namespace std;

int main(){
	int ans = 0;
    char a[205], b[205];
	int l[205][205] = {0};
	gets(a);
	gets(b);

	for(int i = 1; i <= strlen(a); i++){
		for(int j = 1; j <= strlen(b); j++){
			if(a[i-1] == b[j-1]){
			    l[i][j] = l[i-1][j-1] + 1;
			}
			else{
				l[i][j] = max(l[i][j-1], l[i-1][j]);
			}
		}
	}
	cout << l[strlen(a)][strlen(b)] << endl;
}

 

2.防卫导弹

描述:一种新型的防卫导弹可截击多个攻击导弹。它可以向前飞行,也可以用很快的速度向下飞行,可以毫无损伤地截击进攻导弹,但不可以向后或向上飞行。但有一个缺点,尽管它发射时可以达到任意高度,但它只能截击比它上次截击导弹时所处高度低或者高度相同的导弹。现对这种新型防卫导弹进行测试,在每一次测试中,发射一系列的测试导弹(这些导弹发射的间隔时间固定,飞行速度相同),该防卫导弹所能获得的信息包括各进攻导弹的高度,以及它们发射次序。现要求编一程序,求在每次测试中,该防卫导弹最多能截击的进攻导弹数量,一个导弹能被截击应满足下列两个条件之一:
a)它是该次测试中第一个被防卫导弹截击的导弹;
b)它是在上一次被截击导弹的发射后发射,且高度不大于上一次被截击导弹的高度的导弹。

输入:多个测例。
每个测例第一行是一个整数n(n不超过100),第二行n个整数表示导弹的高度(数字的顺序即发射的顺序)。
n=0表示输入结束。

输出:每个测例在单独的一行内输出截击导弹的最大数目。

输入样例

5
5 6 100 6 61
0

输出样例

2

#include<iostream>
using namespace std;

int main(){
	int n;
	int arr[300];
	int l[300];
	int max;
	while(cin >> n && n){
		for(int i = 0; i < n; i++){
		    cin >> arr[i];
			l[i] = 1;
		}
		l[n] = 1;

		for(int i = 1; i < n; i++){
			for(int j = 0; j < i; j++){
				if(arr[j] >= arr[i] && l[i] <= l[j]){
				    l[i] = l[j] + 1;
				}
			}
		}
		max = l[0];
		for(int i = 1; i < n; i++){
			if(max < l[i]){
			    max = l[i];
			}
		}
		cout << max << endl;
	}
}

 

3.田忌赛马

描述:田忌与齐王赛马,双方各有n匹马参赛(n<=100),每场比赛赌注为1两黄金,现已知齐王与田忌的每匹马的速度,并且齐王肯定是按马的速度从快到慢出场,现要你写一个程序帮助田忌计算他最好的结果是赢多少两黄金(输用负数表示)。
Tian Ji and the king play horse racing, both sides have n horse (n is no more the 100), every game a bet of 1 gold, now known king and Tian Ji each horse's speed, and the king is definitely on the horse speed from fast to slow, we want you to write a program to help Tian Ji his best result is win the number gold (lost express with the negative number).

 

输入:多个测例。
每个测例三行:第一行一个整数n,表示双方各有n匹马;第二行n个整数分别表示田忌的n匹马的速度;第三行n个整数分别表示齐王的n匹马的速度。
n=0表示输入结束。
A plurality of test cases.
Each test case of three lines: the first line contains an integer n, said the two sides each have n horse; second lines of N integers n Tian Ji horse speed; third lines of N integers King n horse speed.
N = 0 indicates the end of input.

 

输出:每行一个整数,田忌最多能赢多少两黄金。
how many gold the tian ji win

输入样例

3
92 83 71
95 87 74
2
20 20
20 20
2
20 19
22 18
3
20 20 10
20 20 10
0

输出样例

1
0
0
0

#include<iostream>
#include<algorithm>
using namespace std;

int main(){
	int n;
	int arr1[300],arr2[300];
	int l[300][300];
	while(cin >> n && n){
		for(int i = 0; i < n; i++){
		    cin >> arr1[i];
		}
		for(int i = 0; i < n; i++){
			cin >> arr2[i];
		}
		sort(arr1, arr1+n, greater<int>());
		sort(arr2, arr2+n, greater<int>());
		for(int i = 0; i <= n; i++){
			for(int j = 0; j <= n; j++){
			    l[i][j] = 0;
			}
		}

		for(int i = 1; i <= n; i++){
			for(int j = 1; j <= i; j++){
				if(arr1[j-1] > arr2[i-1]){
				    l[j][i] = l[j-1][i-1] + 1;
				}
				else if(arr1[j-1] == arr2[i-1]){
				    l[j][i] = max(l[j-1][i-1], l[j-1][i] - 1);
				}
				else{
				    l[j][i] = l[j-1][i] - 1;
				}
			}
		}
		cout << l[n][n] << endl;
	}
}

 

4.计算矩阵连乘积

描述:在科学计算中经常要计算矩阵的乘积。矩阵A和B可乘的条件是矩阵A的列数等于矩阵B的行数。若A是一个p×q的矩阵,B是一个q×r的矩阵,则其乘积C=AB是一个p×r的矩阵。计算C=AB总共需要p×q×r次乘法。
现在的问题是,给定n个矩阵{A1,A2,…,An}。其中Ai与Ai+1是可乘的,i=1,2,…,n-1。
要求计算出这n个矩阵的连乘积A1A2…An最少需要多少次乘法。

输入:输入数据的第一行是一个整树n(0 < n <= 10),表示矩阵的个数。
接下来的n行每行两个整数p,q( 0 < p,q < 100),分别表示一个矩阵的行数和列数。

输出:输出一个整数:计算连乘积最少需要乘法的次数。

输入样例

10
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
10 11

输出样例

438

#include<iostream>
using namespace std;



int main(){
    int tmp;
	int i, j, r, k, t;
    int n;
    int arr[100];
    int l[100][100] = {0};
	
	cin >> n;
	for(int i = 0; i < n ;i++){
	    cin >> arr[i] >> tmp;
	}
	arr[n] = tmp;

	for(r = 1; r < n; r++){
		for(i = 1; i < n; i++){
			j = i+r;
			l[i][j] = l[i+1][j] + arr[i-1]*arr[i]*arr[j];
			for(k = i+1; k < j; k++){
			    t = l[i][k] + l[k+1][j] +arr[i-1]*arr[k]*arr[j];
				if(t < l[i][j]){
				    l[i][j] = t;
				}
			}
		}
	}
	cout << l[1][n] << endl;
}

 

5.最长子序列的长度

描述:给定一个序列,求它的最长递增子序列的长度
输入:先输入一个正整数n,表示序列的长度,再输入n个整数表示这个序列

输出:输出它的最长递增子序列的长度

输入样例

7
3 8 6 9 12 100 30

输出样例

5

#include<iostream>
using namespace std;

int main(){
    int n, i, j;
	int ans;
	int arr[1000], list[1000];
    
    cin >> n;
	for(i = 0; i < n; i++){
	    cin >> arr[i];
	    list[i] = 1;
	}

	for(i = 1, ans = 1; i < n; i++){
		for(j = 0; j < i; j++){
			if(arr[j] < arr[i] && list[j]+1 > list[i]){
			    list[i] = list[j] + 1;
			}
            if(list[i] > ans){
		        ans = list[i];
		    }
		}
	}

	cout << ans << endl;
}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值