dp(动态规划(01背包,公共子序列))

之前学的代码以后再慢慢补回来吧,先写今天学的。
dp的算法我自己找了很多视频看,还是没怎么看懂,这类题和贪心题一样想到了dp方程就简单,代码量很少,但就是难想啊!!!

求公共最长上升子序列

hdu 1159
这道题只是要求最长上升的数目
只需要用一个二维数组dp【i】【j】下标分别表示当前为前 i 个组成的子串 和 前 j 个组成的字串的最大公共子序列数。如果当前 i 与 j 对应的字母相同,那么子序列数就加一。 否则就选取 i - 1组成的子串和 j 组成的子串的公共子序列数 与 i 组成的子串和 j-1组成的子串 的公共子序列数的较大值。 好好理解这句话!!!可以用下面的dp方程辅助理解。
if(s[i]==s[j])
dp[i][j]=dp[i-1][j-1]+1;
else
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);

#include <iostream>
#include <cstdio>
#include <cstring>
#include <sstream>
#include <string>
#include <algorithm>
#include <list>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <cstdlib>
#include<iomanip>
#define MAXN 501
using namespace std;
#define ll long long int
ll n,price,m;
ll dp[MAXN][MAXN];
ll c[MAXN];
int main()
{          
        string s1,s2;       
        while(cin>>s1>>s2)
        {   memset(c,0,sizeof(c));
            memset(dp,0,sizeof(dp));
            for(int i=1;i<=s1.length();i++)
             for(int j=1;j<=s2.length();j++)
             {
                if(s1[i-1]!=s2[j-1])
                dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
                else
                dp[i][j]=dp[i-1][j-1]+1;
              } 
            cout<<dp[s1.length()][s2.length()]<<endl;     
        }   
}

先只码01背包

给你一个背包所能承受的最大重量M,现在有N个物品,每个物品有他自己的重量 WI 和 价值 VI 要你求所能组成的最大价值。
我还没写到只有模板的题目…
先把dp方程写出来 dp[j]=max(dp[j],dp[j-v[i]]+w[i]);

for(int i=1;i<=n;i++)
 for(int j=m;j>=c[i];j--)
    dp[j]=max(dp[j],dp[j-v[i]]+w[i]);

猜你喜欢

转载自blog.csdn.net/wnmxhAC/article/details/81569120