zoukankan      html  css  js  c++  java
  • 恶补一下DP+背包专题(刷刷水题)L2

    开心的金明
    题目大意

    就是求一定背包容量的最大值

    思路

    想必大家都知道,一看到这种题目,就会想起01背包

    虽然特别简单但是还是讲一下吧

    状态设置

    由于这题差不多是一个01背包的版子题,那么我们就只需要一个一维的数组去记录状态

    f[i]中i代表的是背包容量,而f[i]的值则代表该容量下的最大值

    转移方程

    f[i]=max(f[i],f[i-背包容量]+背包价值)

    输出

    输出的话我们就只需要输出f[背包容量]就可以啦

    这个简单的DP题就讲完啦

    代码在这里

    小A点菜
     题目大意

    就是要求花光所有钱的方案数

    思路

    最开始我还不懂,发现题解的说法好有道理

    我们设置一个二维数组来统计选到第i种物品花j的钱的方案数

    最后我们就只要输出选到第n种物品话光全部钱的方案数

    状态设置

    f[i][j]中i代表现在选到第几种物品,j代表花的钱数

    转移方程

    1.如果我们枚举的钱数大于菜的价格即(j>a[i])

    f[i][j]=f[i-1][j]+f[i-1][j-a[i]];//这2个式子相加分别代表不选这种物品和选这种物品,但是价格不变的方案数

    2.如果我们枚举的钱数等于菜的价格即(j==a[i])

    f[i][j]=f[i-1][j]+1//这2个值相加代表不选这种物品和选的方案数,由于我们不方便将f[i][0]定义为1,所以这里就特判处理一下(是这么理解的吧...)

    3.如果小于

    f[i][j]=f[i-1][j]//直接转移过来就可以啦

    输出

    直接输出f[n][m]

    #include<bits/stdc++.h>
    using namespace std;
    int n,m;
    int a[1005];
    int f[110][10010];
    int scan()//快读撒
    {
        int as=0,fin=1;
        char c=getchar();
        while(c<'0'||c>'9'&&c!='-') c=getchar();
        if(c=='-') fin=-1;
        while(c>='0'&&c<='9')
        {
            as=(as<<3)+(as<<1)+c-'0';
            c=getchar();
        }
        return as;
    }
    int main()
    {
        n=scan();
        m=scan();
        for(int i=1;i<=n;i++)
        {
            a[i]=scan();
    //        cout<<a[i]<<endl;
        }
        for(int i=1;i<=n;i++)//在这里面,i就像一个分层,所以我们没有必要倒着来
        {
            for(int j=1;j<=m;j++)
                {
                    if(j>a[i]) f[i][j]=f[i-1][j]+f[i-1][j-a[i]];
                    else if(j==a[i]) f[i][j]=f[i-1][j]+1;
                    else  f[i][j]=f[i-1][j];
                    //        cout<<i<<" "<<j<<" "<<f[i][j]<<endl;
                }
        }
        cout<<f[n][m];
        return 0;
    }
    /*
    思路:
    这题的话最开始有点蒙
    现在来理一下思路
    1.我们设置状态f[i][j],i是前i中,j是前,值为种数
    2.
    f[i][j]=f[i-1][j]+f[i-1][j-a[i]];//这种转移只是一个向前走的过程
    f[i][j]=f[i-1][j]+1;//这种是方案添加
    f[i][j]=f[i-1][j];//相当于不选择这种商品
    大概是这样子吧
    ......... 
    DP还是要多练一练啊
    */
    代码在这里

    金明的预测

    让我拖一会,先把简单题写完233333


    疯狂的采药

    题目描述

    这个题目实质上就是一个求完全背包的问题

    思路

    我们就设置一个一维数组来记录相应容量的最大值

    状态设置

    f[i]中i代表容量,f[i]是该容量的值

    转移方程

    由于这个不是01背包,而是完全背包,所以我们枚举时要正着枚举,而不是像01背包一样倒着枚举

    f[i]=max(f[i],f[i-a[i]]);

    输出

    直接输出f[m]就可以了...

    #include<bits/stdc++.h>
    using namespace std;
    int T,n;
    int f[100010]={0};
    struct ss
    {
        int wei,val;
    }a[10010];
    int scan()
    {
        char c=getchar();
        int as=0,f=1;
        while(c>'9'||c<'0'&&c!='-') c=getchar();
        if(c=='-') f=-1;
        while(c>='0'&&c<='9')
        {
            as=(as<<3)+(as<<1)+c-'0';
            c=getchar();
        }
        return f*as;
    }
    int main()
    {
        T=scan();
        n=scan();
        for(int i=1;i<=n;i++)
        {
            a[i].wei=scan();
            a[i].val=scan();
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=a[i].wei;j<=T;j++)
            {
                f[j]=max(f[j],f[j-a[i].wei]+a[i].val);
            }
        }
        cout<<f[T];
        return 0;
    }
    /*
    思路:
    我们只需要开一个一维数组,来表示背包的容量,
    然后我们只需要在01背包的基础上将容量从小枚举到大
    */
    代码在这里

     
  • 相关阅读:
    前后端分离项目采用Prerender的SEO优化流程
    spring多数据源分布式事务的分析与解决方案
    Windows上MyEclipse2017 CI7 安装、破解以及配置
    WINDOWS上JDK安装与环境变量设置
    Abp Vnext Vue3 的版本实现
    你好,年轻人
    数据结构·堆
    数据结构·优先队列
    算法笔记·并查集
    JAVA问题解决——Jar包中资源调用
  • 原文地址:https://www.cnblogs.com/KSTT/p/10333223.html
Copyright © 2011-2022 走看看