C++ 动态规划例题详解
递推问题
利用递推解决问题,我们就要模仿求斐波那契数列的过程。首先,确定几个规模较小的问题答案。然后考虑如何由这几个规模较小的答案推得后面的答案。一旦有了递推规则和数列初始的几个值,计算机程序就能帮助我们求解数列后面的所有数字,我们的问题也得到了解决。
例题1:
代码:
//
// 93.cpp
// N阶楼梯上楼问题
//
// Created by chenmeiqi on 2019/4/17.
// Copyright © 2019年 chenmeiqi. All rights reserved.
//
#include <iostream>
using namespace std;
// 递归解法
int getKind(int n){
if(n==1) return 1;
else if(n==2) return 2;
else {
return getKind(n-1)+getKind(n-2);
}
}
int main(int argc, const char * argv[]) {
int n;
long long res[90]; // res数组保存数列的每一个值,由于数值过大,我们需要使用long long类型
while (cin>>n) {
// cout<<getKind(n)<<endl; // 递归解法
res[1]=1;
res[2]=2;
for (int i=3; i<=n; i++) {
res[i]=res[i-1]+res[i-2];
}
cout<<res[n]<<endl;
}
return 0;
}
分析:
例题2:
代码:
//
// 94.cpp
// 不容易系列之一
//
// Created by chenmeiqi on 2019/4/17.
// Copyright © 2019年 chenmeiqi. All rights reserved.
//
#include <iostream>
using namespace std;
int getKinds(int n){
if(n==1){
return 0;
}
else if(n==2){
return 1;
}
else{
return (n-1)*getKinds(n-1)+(n-1)*getKinds(n-2);
}
}
int main(int argc, const char * argv[]) {
int n;
while (cin>>n) {
cout<<getKinds(n)<<endl;
}
return 0;
}
分析:(错排公式)
最长递增子序列(LIS)
例题:
代码:
//
// 95.cpp
// 拦截导弹
//
// Created by chenmeiqi on 2019/4/17.
// Copyright © 2019年 chenmeiqi. All rights reserved.
//
#include <iostream>
#include <algorithm>
using namespace std;
bool cmp(int a,int b){ // 从高到低排
return a>b;
}
int main(int argc, const char * argv[]) {
int k;
int a[26];
int max;
while (cin>>k) {
int res[26]={0}; // 初始化,便于排序
for (int i=0; i<k; i++) {
cin>>a[i];
}
res[0]=1; // 初始化0位置的最长子序列为1
for (int i=1; i<k; i++) {
res[i]=1;
max=1;
for (int j=i-1; j>=0; j--) {
if (a[i]<=a[j] && res[j]+1>max) { // “不高于”
res[i]=res[j]+1;
max=res[i];
}
}
}
sort(res, res+26,cmp); // 排序
cout<<res[0]<<endl;
}
return 0;
}