C++ 动态规划例题详解

这篇博客详细讲解了使用C++进行动态规划的若干问题,包括递推问题的解题思路,如斐波那契数列;最长递增子序列(LIS)和最长公共子序列(LCS)的例题分析及代码实现;还探讨了不同类型的背包问题,如0-1背包、完全背包和多重背包的状态与状态转移策略,并给出了相关代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

递推问题

利用递推解决问题,我们就要模仿求斐波那契数列的过程。首先,确定几个规模较小的问题答案。然后考虑如何由这几个规模较小的答案推得后面的答案。一旦有了递推规则和数列初始的几个值,计算机程序就能帮助我们求解数列后面的所有数字,我们的问题也得到了解决。

例题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) {      // “不高于”
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值