【无标题】

在这里插入图片描述总算是有些发了狠,不能再摸下去了这里从dp开始,争取每天一篇+
这里直接以01背包为例01


一、dp是什么?

动态规划
看一步走一步,要的最多(bushi贪心)

二、使用步骤


在这里插入图片描述

1.状态表示

在本题中,我们要考虑在N个物品内选择不超过体积V的i件物品,
我们用v[i]来表示各物品体积,w[i]表示价值。那么,根据闫氏dp我们规定:
f[i][j]为前i件物品且体积不超过j的物品的价值,那么,我们求的就是
前N件物品且体积不超过V的价值f[N][V]


2.状态计算

对于f[i][j]我们考虑一下2种情况:

1.当j(我们给的体积)小于v[i]时第i件物品放不下

那么其递推公式为:f[i][j]=f[i-1][j]
因为放不下,体积不变

2.当j(我们给的体积)小于v[i]时第i件物品放得下

那么其递推公式为:f[i][j]=max(f[i-1][j],f[i-1][j-v[i]]+w[i])
max第一个直接不放,第二个是放得下,但要退回第i-1个体积j-去第i个的体积再加w[i]


三.代码

#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <iomanip>
//#include <bits/stdc++.h>
using namespace std;


int v[1001], w[1001];//体积,与 价值

int f[1001][1001];//前i项不超过体积v的价值

bool cmp(int a, int b)
{
    return a > b;
}



int main()
{
    int N, V;//输入N个,最大体积V
    cin >> N >> V;

    for (int i = 1; i <= N; i++)
    {
        cin >> v[i] >> w[i];
    }

    for (int i = 1; i <= N; i++)
    {
        for (int j = 0; j <= V; j++)
        {
            if (j < v[i])//如果此时给的体积小于v[i]的话,就放不进去
            {
                f[i][j] = f[i - 1][j];//所以此时第i项的价值等于第前i-1项的
            }
            else
            {
                //否则         不放第i个   放第i个
                f[i][j] = max(f[i - 1][j], f[i - 1][j - v[i]] + w[i]);
            }
        }
    }

    cout << f[N][V];
    return 0;
}

四.优化

观察易发现第i项用的都是第i-1项的

f[i][j] = f[i - 1][j];

f[i][j] = max(f[i - 1][j], f[i - 1][j - v[i]] + w[i]);

我们考虑删除为:

f[j] = f[j];
但是j-v[i]却用的还是第i项的,怎么变成第i-1项呢?用减法,具体见代码
f[j] = max(f[j], f[j - v[i]] + w[i]);

#include <iostream>
#include <bits/stdc++.h>
using namespace std;

int v[1001],w[1001],f[1001];

int main()
{
	int N,V;
	cin>>N>>V;
	for(int i=1;i<=N;i++)
	{
		cin>>v[i]>>w[i];
	}

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

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值