基础dp

一  : 0 1 背包 

设  f [  i ]  [ j ]  表示 选了  i  个物品  容量 为 j  的背包,状态直接转移

0 - >  V  枚举 和  V  -  > 0  枚举都可

        for(int i=1;i<=n;i++){
            for(int j=0;j<=V;j++){
                if(w[i]>j)f[i][j]=f[i-1][j];
                else f[i][j]=max(f[i-1][j],f[i-1][ j - w[i] ]+v[ i ]);
            }
        }
View Code

滚动数组 :

逆序枚举

        memset(f,0,sizeof f);
        for(int i=1;i<=n;i++){
            for(int j=V;j>=w[i];j--){
             f[j]=max(f[j],f[ j - w[i] ]+v[ i ]);
            }
        }
View Code

 

 二 :最长公共子序列 

设  f [ i  ] [ j ]  表示 枚举到 字符串1 的 i - 1 位  到 字符串2 的 j  - 1 位

直接转移

        for(int i=1;i<=len1;i++){
            for(int j=1;j<=len2;j++){
                if(s1[i-1]==s2[j-1]){
                dp[i][j]=dp[i-1][j-1]+1;
                }
                else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
            }
        }
View Code

 

 三  :  最长上升子序列

设   f [ i  ]  表示 第  i  为的最长 上升子序列 ,直接转移

int LIS()
{
    dp[1]=1;
    int ans=1;
    for(int i=2;i<=n;i++)
    {
        int m=0;
        for(int j=1;j<i;j++)
        {
            if(dp[j]>m&&a[j]<a[i])
                m=dp[j];
        }
        dp[i]=m+1;
        if(dp[i]>ans)
            ans=dp[i];
    }
    return ans;
}
View Code

The Triangle

 POJ - 1163 

设 sum [ i ] [ j ] 表示  从  i  行 j  列走的最大值,那么从上向下递推即可

for(int j=1;j<=n;j++)sum[n][j]=a[n][j];
    for(int i=n-1;i>=1;i--){
    for(int j=1;j<=i;j++){
    sum[i][j]=a[i][j]+max(sum[i+1][j],sum[i+1][j+1]);
    }
    }
View Code

 

posted @ 2020-07-03 20:28  无声-黑白  阅读(148)  评论(0编辑  收藏  举报