动态规划经典题解

#include <iostream>
#include <algorithm>
#include <limits.h>
#include <fstream>
#include <string.h>
using namespace std;
//斐波那契数 用数组存中间变量
int f(int n)
{
    vector<int> F(n + 1, 0);
    F[1] = F[2] = 1;
    for(int i = 3; i < n; i++){
        F[i] = F[i - 1] + F[i - 2];
    }
    return F[n];
}
int a[2000][2000]; //声明全局数组 可以有默认初始化
int main()
{
    //    int a[100];
    //    int dp[12];
    //    memset(dp, 65535, sizeof(dp));
    //    for(int i = 0; i < 12; i++){
    //        dp[i] = INT_MAX;
    //    }
    //    freopen("in.txt", "r", stdin);
    //    int n = 11;
    //    for(int i = 0; i < 3; i++){
    //        cin >> a[i];
    //    }
    ////////////////////////////////////////////////
    //    int sum = 0;
    //    int ans = INT_MIN;
    //    最大上升Sum值
    //    for(int i = 0; i < n; i++){
    //        sum += a[i];
    //        ans = max(sum,ans);
    //        if(sum < 0){
    //            sum = 0;
    //        }
    //    }
    ////////////////////////////////////////////////
    //    最大上升乘积值
    //    if(n == 0){
    //        return 0;
    //    }else if(n == 1){
    //        return a[0];
    //    }
    //    int p = a[0];
    //    int maxP = a[0];
    //    int minP = a[0];
    //    for(int i = 1; i < n; i++){
    //        int t = maxP;
    //        maxP = max(max(maxP * a[i], a[i]),minP * a[i]);
    //        minP = min(min(minP * a[i], a[i]),t * a[i]);
    //        p = max(maxP, p);
    //    }
    //    cout << maxP ;

    ////////////////////////////////////////////////
    //    换钱 dp思想
    //    dp[0] = 0;
    //    for(int i = 1; i <= n; i++){
    //        for(int j = 0; j < 3; j++){
    //            if(i >= a[j] && dp[i - a[j]] + 1 <= dp[i]){
    //                dp[i] = dp[i - a[j]] + 1;
    //            }
    //        }
    //    }
    //    cout << dp[n];
    ////////////////////////////////////////////////
    //    数塔问题 走那些点等到的值最大
    //    freopen("in.txt","r",stdin);
    //    int n;
    //    cin >> n;
    //    for(int i = 0; i < n; i++){
    //        for(int j = 0; j <= i; j++){
    //            cin >> a[i][j];
    //        }
    //    }
    //    for(int i = n-1; i > 0; i--){
    //        for(int j = 0; j < i; j++){
    //            a[i - 1][j] += max(a[i][j],a[i][j + 1]);
    //        }
    //    }
    //    cout << a[0][0];
    ////////////////////////////////////////////////
    //    最长上升子序列
    //    const int n = 9;
    //    freopen("in.txt","r",stdin);
    //    int a[100] = {0};
    //    int d[100] = {0};
    //    int ans = 0;
    //    for(int i = 0; i < n; i++){
    //        cin >> a[i];
    //    }
    //    //状态转移方程
    //    //d(i) = max{1, d(j)+1},其中j<i,A[j]<=A[i]
    //    //用大白话解释就是,
    //    //想要求d(i),就把i前面的各个子序列中
    //    //最后一个数不大于A[i]的序列长度加1,然后取出最大的长度即为d(i)。
    //    //当然了,有可能i前面的各个子序列中最后一个数都大于A[i],那么d(i)=1,
    //    //即它自身成为一个长度为1的子序列。
    //    for(int i = 0; i < 9; i++){
    //        d[i] = 1;
    //        for(int j = 0; j < i; j++){
    //            if(a[j] < a[i] && d[j] + 1 > d[i]){
    //                d[i] = d[j] + 1;
    //            }
    //        }
    //        ans = max(ans,d[i]);
    //    }
    //    cout << ans;
    ////////////////////////////////////////////////
    //  最长上升公共子序列
    //    freopen("in.txt","r",stdin);
    //    //freopen("out.txt","w",stdout);
    //    string str1,str2;
    //    cin >> str1 >> str2;
    //    int dp[200][200];
    //    memset(dp,0,sizeof(dp));
    //    int lenA = str1.length();
    //    int lenB = str2.length();
    //    int ans = 0;
    //    for(int i = 1; i <= lenA; i++){
    //        for(int j = 1; j <= lenB; 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]);
    //            }
    //        }
    //    }
    //    cout << dp[lenA][lenB] ;
    ////////////////////////////////////////////////
    //    吃苹果问题 只能向下或者向右
    //    int dp[100][100];
    //    int a[3][4] = {
    //                23, 45, 56, 32,  // 正确路线为 23 45 56 32 21 90
    //                18, 19, 20, 21,
    //                7, 19, 20, 90
    //            };
    //    memset(dp, 0, sizeof(dp));
    //    //int ans  = 0;
    //    dp[0][0] = a[0][0]; //初始化
    //    for(int i = 0; i < 3; i++){
    //        for(int j = 0; j < 4; j++){
    //            if(i == 0 && j == 0) continue;
    //            dp[i][j] = max((j==0)?0:dp[i][j-1],(i==0)?0:dp[i-1][j]) + a[i][j];
    //        }
    //    }
    //    cout << dp[2][3];
    ////////////////////////////////////////////////
    //    背包问题 有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。
    //    求解将哪些物品装入背包可使价值总和最大。
    //    最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。
    //    即第i件放还是不放
    //    用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是:
    //    f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]} 放的话前i-1件物品放入剩下的容量为v-c[i]的背包中
    //    for(int i = 1; i <= n; i++)
    //    {
    //        for(int j = 0; j <= W; j++)
    //        {
    //            if(j < w[i]) //如果当前的容量不足以承受第i个物品的重量
    //                dp[i][j]  = dp[i-1][j];
    //            else
    //                dp[i][j] =  max(dp[i-1][j], dp[i-1][j - w[i]] + v[i]);
    //        }
    //    }

    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值