用多少眼泪才能让你相信 发表于 2025-4-4 13:26:28

蓝桥杯 Day15 动态规划 背包题目

01背包 

1、小明的背包

标题链接:小明的背包1 - 蓝桥云课 

https://i-blog.csdnimg.cn/direct/8f884a02c5ee4f47a6d724c5a0e6d271.png
1、递推(自下而上)

#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;

int n,v;   //物品数目,背包容量
int w,p;
int dp;
int main()
{
        cin>>n>>v;
        for(int i=1;i<=n;i++)
                cin>>w>>p;
               
        for(int i=1;i<=n;i++)
        {
                for(int j=0;j<=v;j++)
                {
                        if(w>j)
                                dp = dp;
                        else
                                dp= max(dp,dp]+p);       
                }       
        }
        cout<<dp<<endl;
        return 0;
}
 2、滚动数组

#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;

int n,v;   //物品数目,背包容量
int w,p;
int dp;
int main()
{
        cin>>n>>v;
        for(int i=1;i<=n;i++)
                cin>>w>>p;
               
        for(int i=1;i<=n;i++)
        {
                for(int j=v;j>=w;j--)
                {
                        dp=max(dp,dp]+p);       
                }       
        }
        cout<<dp<<endl;
        return 0;
}
01背包方案数(组合数) 

2、2022

标题链接: 2022 - 蓝桥云课
https://i-blog.csdnimg.cn/direct/050630d9de0c44c3bb402a10ca89036c.png
答案: 
379187662194355221
         解题思路:本题是求解01背包的方案数。可以看作01背包,向背包中装入10个物品,每种物品只有一个,每个物品的体积是1~2022,背包容量是2022。
1、非滚动数组

        由于物品体积不确定,我们多界说一维,界说 dp 表示从数字1~i中取j个数和为k的方案数,然后进行分析。
(1)k>=i,即背包容量>=物品体积。那么i可以取,也可以不取。
        ①取i。从1~i中取 j-1个数,再取i,等价于 dp 
        ②不取i。从1~i中取 j个数,等价于dp
此时的方案数应该为两种情况之和,即dp = dp + dp
(2)k<i,即背包容量<物品体积。取不了i
        dp = dp
#include<bits/stdc++.h>
using namespace std;
const int N=3e3;

//dp:表示从数字 1~i里面取 j个数,和为 k的方案数
long long dp={0};   

int main()
{
        //初始化dp,注意 i 从0开始
        for(int i=0;i<=2022;i++)
        {
                dp=1;
        }
        //物品体积是1~2022
        for(int i=1;i<=2022;i++)
        {
                //物品
                for(int j=1;j<=10;j++)
                {
                        //背包容量
                        for(int k=1;k<=2022;k++)
                        {
                                //i不能取
                                if(i>k)
                                        dp=dp;
                                //i可以取
                                else       
                                                //方案数 = 不取 i的方案数 + 取 i的方案数
                                        dp=dp+dp;
                        }
                }
        }
        cout<<dp;
        return 0;
               
                       
}  
2、滚动数组

        dp:将 k 拆分成 j 个不同正整数的方案数。
        留意:如果从小到大遍历 j,那么在更新 dp 时, dp 大概已经被更新过,导致重复盘算。倒序遍历可以确保每次更新dp 时,dp 是基于之前的状态,而不是当前循环中已经更新过的状态。
#include<bits/stdc++.h>
using namespace std;
const int N=3e3;
long long dp={0};   

int main()
{
        //初始化 :表示选择0个数,和为0的方案数为1
        dp=1;

        for(int i=1;i<=2022;i++)
        {
                //注意j从大到小取
                for(int j=10;j>=1;j--)
                {
                        for(int k=i;k<=2022;k++)
                        {
                                dp += dp;
                        }
                }
        }
        cout<<dp;
        return 0;                
}  
3、优化

        dp:将 i 拆分为 j 个不同正整数的方案数。我们可以将题目分为两种情况:
(1)j 个数都大于等于 2。
        此时,将每个数减 1,得到 j 个新的数(仍互不相同且 >=1),它们的和为 i - j 。对应的方案数为 dp。
(2)j个数里面包含数字 1。 
        剩下的 j-1 个数必须 >=2 且互不相同,它们的和为 i-1 。将这些数减 1,则 j-1个数的和等于(i-1) - (j-1) = i - j。对应的方案数为 dp 。
因此,总方案数为两种情况的叠加:dp = dp (不包含1) + dp (包含1)。
#include <bits/stdc++.h>
using namespace std;
const int N=3e3;
long long dp={1};

int main()
{
    for(int i=1; i<=2022;i++)
    {
            for(int j=1;j<=10;j++)
            {
                    if(i>=j)
                                dp = dp+dp;
                }
        }
    cout<<dp;
}
完全背包

1、小明的背包

标题链接:小明的背包2 - 蓝桥云课 
https://i-blog.csdnimg.cn/direct/00b2923914d54531860c7f083b2c9b89.png
         参考:代码随想录 
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;

int n,v;   //物品数目,背包容量
int w,p;
int dp;
int main()
{
        cin>>n>>v;
        for(int i=1;i<=n;i++)
                cin>>w>>p;
               
        for(int i=1;i<=n;i++)
        {
                for(int j=w;j<=v;j++)
                {
                        dp= max(dp,dp]+p);       
                }       
        }
        cout<<dp<<endl;
        return 0;
}
2、纪念品

标题链接:纪念品 - 蓝桥云课 
             ​​https://i-blog.csdnimg.cn/direct/b1fd4b98afa846fd9fd73bc32b4753b4.png            ​​https://i-blog.csdnimg.cn/direct/4055f4bb4aac457095a87ff2194f43a6.png 
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M=1e4+10;
const int N=1e3+10;

ll t,n,m;
ll a,dp;

int main()
{
        cin>>t>>n>>m;
        for(int i=1;i<=t;i++)
        {
            for(int j=1;j<=n;j++)
              cin>>a;
        }
        //天数
        for(int i=1;i<=t-1;i++)
        {
                //每天的利润,采用贪心,今天买明天卖
            memset(dp, 0, sizeof(dp));
            //物品
            for(int j=1;j<=n;j++)
            {
                    //背包容量
                       for(ll k=a;k<=m;k++)
                      {
                      dp=max(dp,dp]+a-a);
                      }
            }
            m+=dp;
        }
        cout<<m<<endl;
        return 0;
}
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 蓝桥杯 Day15 动态规划 背包题目