动态规划模型列举

(1)最大连续子序列和

令dp[i]表示以A[i]作为末尾的连续序列的最大和

    dp[0] = A[0];
    for(int i =1;i < index;i++){
        dp[i] =max(A[i],A[i] + dp[i - 1]);//状态转移方程
    }
    for(int i = 0;i < index;i++){
        if(dp[i] > maxsum){
            maxsum = dp[i];
        }
    }

(2)最长不下降子序列(LIS)

令dp[i]表示以A[i]结尾的最长不下降子序列长度

    int ans = -1;//记录最大的dp[i]
    for (int i = 1; i <= n; ++i)//按顺序计算出dp[i]
    {
        dp[i] = 1;//边界
        for (int j = 1; j < i; ++j)
        {
            if(A[j] <= A[i] && (dp[j] + 1 > dp[i])){
                dp[i] = dp[j] + 1;//状态转移方程
            }
        }
        ans = max(ans, dp[i]);
    }

(3)最长公共子序列(LCS)

令dp[i][j]表示字符串A的i号位和字符串B的j号位之前的LCS长度

	for (int i = 1; i < alen; i++)
		dp[i][0] =  0;
	for (int j = 1; j < blen; j++)
		dp[0][j] = 0;
	for (int i = 1; i < alen; i++)
		for (int j = 1; j < blen; j++)
		{
			if (A[i] == B[j])
				dp[i][j]=dp[i-1][j-1]+1;
			else
				dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + 1);
		}

(4)最长回文子串

令dp[i][j]表示S[i]至S[j]所表示的子串是否是回文子串

	for(int i=0;i<len;i++)
	{
		dp[i][i]=1;
		if(i<len-1)
			if(S[i]==S[i+1])
			{
				dp[i][i+1]=1;
				ans=2;//初始化时注意当前最长回文子串长度;
			}
	}
	//状态转移方程
	for(int L=3;L<=len;L++)//枚举子串长度
		for(int i=0;i+L-1<len;i++)/
		/枚举子串起始端点 起始端点加上子串长
		(子串长度包括他本身,所以要-1)必须小于总长,
			{
				int j=i+L-1;//子串右端点
				if(S[i]==S[j]&&dp[i+1][j-1]==1)
				{
					dp[i][j]=1;
					ans=L;//更新最长回文子串长度;
				}
			}

(5)数塔DP

令dp[i][j]表示从第i行第j个数字出发的到达最底层的所有路径上所能得到的最大和

	for(int i=1; i<=n; i++)//边界
        b[n][i]=a[n][i];
    for(int i=n-1; i>=1; i--)//动态转移方程
        for(int j=1; j<=i; j++)
           b[i][j]=a[i][j]+max(b[i+1][j],b[i+1][j+1]);

(6) DAG最长路

令dp[i]表示从i号顶点出发能获得的最长路径长度

int DP(int i){
    if(vis[i]) return dp[i];	// dp[i]已计算得到
    vis[i] = true;
    for(int j = 0 ; j < n ; j++){
        if(G[i][j] != INF){
            dp[i] = max(dp[i],DP(j)+G[i][j]);
        }
    }
    return dp[i];	// 返回计算完毕的dp[i]
}

(7) 01背包

令dp[i][V]表示前i件物品恰好装入容量为v的背包中能获得的最大价值

for(int v=0;i<=V;v++)
	dp[v]=0;
for(int i=1;i<=n;i++)
        for(int v=w[i];v<=V;v++)
        	//动态转移方程
            dp[i][v]=max(dp[i-1][v],dp[i-1][j-w[i]]+c[i]);
//滚动数组
//    for(int i=1;i<=n;i++)
//        for(int v=V;v>=w[i];v--)
//       	dp[v]=max(dp[v],dp[v-w[i]]+c[i];

(8)完全背包

令dp[i][v]表示前i件物品恰好装入容量为V的背包中能获得的最大价值

    for ( int i = 1; i <= n; i++ ) {
        for ( int j = 0; j <= W; j ++) {
            for (int k = 0; k*w <= j; k++) {
                f[i][j] = max(f[i-1][j],f[i-1][j-w[i]*k] + v[i]*k);
//滚动数组
//for ( int i = 1; i <= n; i++ ) {
//      for ( int j = w[i]; j <= W; j ++) {
//          f[j] = max(f[j],f[j-w[i]] + v[i]);
//      }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值