概述
1.01背包
我们遍历每一种物品,每种物品都有取或不取两种选择。【背包容量由大到小进行更新】
初始化:dp[0] [i] = 0, 其中 0 ≤ i ≤ m
目标值:dp[n] [m]
int dp[maxn][maxm];//用 dpi 表示遍历到第 i 件物品,且背包容量为 j 时的最大总价值。
void init() {//初始化
for(int i = 0; i <= m; i++) {
dp[0][i] = 0;
}
}
for(int i=1;i<=n;i++){//遍历每一件物品
for(int j=m;j>=0;j--){//背包重量递减
//如果放不下了肯定不能硬塞
if(j < w[i]) {
dp[i][j] = dp[i - 1][j];
}
//如果能放的下
else {//就看看要不要放入这件物品
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]); }
}
}
}
printf("%d", dp[n][m]);//输出答案
改进代码
int dp[maxn];//表示容量为maxn是的最大价值
memset(dp,0,sizeof(dp));//初始化
for(int i=1;i<=n;i++ ){//遍历每一种物品
for(int j=m;j> w[i];j--){{//注意j一定要由大到小更新,且下界为w[i]
dp[j]= max(dp[j], dp[j - w[i]] + v[i]);//dp[j]容量为j时不拿第i件物品 dp[j - w[i]] + v[i] 容量为j时拿第i件物品
}
}
printf("%d",dp[m]);
2.最长公共子序列
int dp[maxn][maxn];
void init(int n, int m) {//初始化
for(int i = 0; i < n; i++) {
dp[i][0] = 0;
}
for(int i = 0; i < m; i++) {
dp[0][i] = 0;
}
}
void LCS(string s1, string s2) {
int n = s1.length(), m = s2.length();//两个字符串从下标为1开始存
init(n, m);
for(int i = 1; i < n; i++) {//每一位遍历
for(int j = 1; j < m; j++) {
if(s1[i] == s2[j]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
}
else {
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
}
3.最长上升子序列
int len;//LIS的长度
int s[maxn];//存储原始序列
int dp[maxn];
void init() {//初始化
//序列第一位直接放进去就行
len = 1;
dp[len] = s[1];
}
void LIS() {//从下标为1开始存储数据
init();
for(int i = 2; i <= n; i++) {//n为所给序列长度
if(s[i] > dp[len]) {//如果比当前LIS最后一位要大就直接接上去
dp[++len] = s[i];
}
else {//否则就修改数据
int pos = lower_bound(dp + 1, dp + len + 1, s[i]) - dp;
dp[pos] = s[i];
}
}
}
4.最大递增子序列和
#include<cstdio>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
//max,min,swap,unique
//dp[i]:以i结尾的数字可构成的最大和
// dp[i] = max(num[i] , dp[j:(1~i-1)] + num[i]) num[i] > num[j]
int num[1000+5];
int dp[1005]; //表示以 第i个数字 结尾的子串的最大和
int main()
{
int n;
while (~scanf ("%d",&n) && n)
{
for (int i = 1 ; i <= n ; i++)
scanf ("%d",&num[i]);
int ans = -INF;
for (int i = 1 ; i <= n ; i++)
{
dp[i] = num[i];
for (int j = 1 ; j < i ; j++)
{
if ( num[j]<num[i] )
dp[i] = max(dp[i] , dp[j] + num[i]);
ans = max(ans , dp[i]);
}
}
printf ("%dn",ans);
}
return 0;
}
最后
以上就是腼腆河马为你收集整理的ACM基础(一)--动态规划的全部内容,希望文章能够帮你解决ACM基础(一)--动态规划所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复