动态规划

dp问题,关键是寻找到递推关系式。
主要也就是几类核心问题,可统一整理。

最长递增子序列

从一个整的序列中,取出一个子序列,使其能够保持递增的性质
F(1)=1;
F(i) = max{1,F[j]+1|j

#include<iostream>
#include<cstdio>
#include<queue>
#include<cmath>
#include<algorithm>
#include<cmath>
using namespace std;

int max(int a, int b){
    if(a<b)
        return b;
    return a;

}

int main(){

    int k,a[25],dp[25];
    while(cin>>k){
        for(int i=0;i<k;i++){
            cin>>a[i];
            dp[i]=0;
        }
        for(int j=0;j<k;j++){
            int tmax = 1;
            for(int m=0;m<j;m++){
                if(a[m]>=a[j]){
                    tmax = max(dp[m]+1,tmax);
                }
            }
            dp[j] = tmax;
        }
        int summax = 0;
        for(int t=0;t<k;t++){
            summax = max(summax,dp[t]);
        }
        printf("%d\n",summax);
    }
    return 0;
}

最长公共子序列

这里写图片描述

#include<iostream>
#include<cstdio>
#include<queue>
#include<cmath>
#include<algorithm>
#include<cmath>
#include<string.h>
using namespace std;

int max(int a ,int  b){
    if(a>b)
        return a;
    else
        return b;
}

int main(){

    char s1[102],s2[102];
    int dp[101][101];
    while(scanf("%s %s",s1,s2)!=EOF){
        int len1 = strlen(s1);
        int len2 = strlen(s2);
        //先初始化
        for(int i=0;i<=len2;i++)
            dp[0][i]=0;
        for(int j=0;j<=len1;j++)
            dp[j][0]=0;
        for(int p=1;p<=len1;p++)
            for(int q=1;q<=len2;q++){
                if(s1[p-1]==s2[q-1])
                    dp[p][q] = dp[p-1][q-1]+1;
                else
                    dp[p][q] = max(dp[p-1][q],dp[p][q-1]);
            }
        printf("%d\n",dp[len1][len2]);

    }
    return 0;
}

注意初始化的代码

01背包

即考察存在或者不存在

#include<iostream>
#include<cstdio>
#include<queue>
#include<cmath>
#include<algorithm>
#include<cmath>
#include<string.h>
using namespace std;

int max(int a ,int  b){
    if(a>b)
        return a;
    else
        return b;
}

int main(){

    int T,M,time[101],value[101],dp[101][1001];
    while(cin>>T>>M){
        for(int i=1;i<=M;i++){
            cin>>time[i]>>value[i];
        }
        //初始化,前0个物品为0
        for(int j=0;j<=T;j++)
            dp[0][j]=0;

        for(int p=1;p<=M;p++){
        //两种情况,q是否大于当前重量
            for(int q=T;q>=time[p];q--)
                dp[p][q] = max(dp[p-1][q-time[p]]+value[p],dp[p-1][q]);
            for(int t=time[p]-1;t>=0;t--)
                dp[p][t] = dp[p-1][t];
        }
        printf("%d\n",dp[M][T]);
    }
    return 0;
}
阅读更多

扫码向博主提问

千叶正志

非学,无以致疑;非问,无以广识
去开通我的Chat快问
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/nghuyong/article/details/73887867
个人分类: 算法
上一篇递归
下一篇logging模块,还在使用print打印?
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭