之前学的代码以后再慢慢补回来吧,先写今天学的。
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]);