10.19—動態規劃 //最長公共子序列//防衛導彈//田忌賽馬//計算矩陣連乘積//最長子序列的長度
阿新 • • 發佈:2019-02-18
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;
}