完全背包——01背包方法数

这两天搞完01背包之后学习了完全背包这个完全背包是指物品数量无限,让自己来装考虑一下状态转移f[i][j]=max(f[i-1][j])尚未选择第i种物品,f[i][j]=max(f[i][j-w[i]+v[i]]);从第i键物品中选择一个显然状态是由不拿当前物品上一层的最优解和当前拿这个物品的最优解来进行比较从而进行转移。当然目标可以是maxf[n][j]或者是f[n][m]这两种都行只不过前者可以判断背包是否能被装满。

下面是二维的代码:

#include<ctime>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdio>
#include<iomanip>
#include<map>
#include<queue>
#include<stack>
#include<cstring>
#include<string>
#include<vector>
using namespace std;
inline long long read()
{
    long long x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
const long long maxn=10001;
long long f[maxn][maxn],w[maxn],v[maxn];
long long n,m;
int main()
{
    //freopen("1.in","r",stdin);
    m=read();n=read();
    for(long long i=1;i<=n;i++)
    {
        v[i]=read();w[i]=read();
    }
    for(long long i=1;i<=n;i++)
        for(long long j=1;j<=m;j++)
        {
            f[i][j]=max(f[i][j],f[i-1][j]);
            if(j>=w[i])f[i][j]=max(f[i][j],f[i][j-w[i]]+v[i]);
        }
    printf("%lld\n",f[n][m]);
    return 0;
}

而一维的完全背包是那样子的,把f[j]=max(f[j-w[i]]+v[i]);正序来选择因为可以在刚刚更新过的第i件物品之上再进行更新这样的话就意味着一件物品有无数件了。不算是很懵了

下面是一维的代码:

#include<ctime>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdio>
#include<iomanip>
#include<map>
#include<queue>
#include<stack>
#include<cstring>
#include<string>
#include<vector>
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
const int maxn=10001;
int f[maxn],w[maxn],v[maxn];
int n,m;
int main()
{
    //freopen("1.in","r",stdin);
    m=read();n=read();
    for(int i=1;i<=n;i++)
    {
        v[i]=read();w[i]=read();
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=w[i];j<=m;j++)
        {
            f[j]=max(f[j],f[j-w[i]]+v[i]);
        }
    }
    cout<<f[m]<<endl;
    return 0;
}

又搞了一道01背包的方法数,这个还是比较简单的个人觉得方法数的话以下面的洛谷例题为例:

求出所有背包的数量,这样的话求助了学长,不会啊当时感觉特别困难做题没有举一反三的能力感觉自己还不行,灵性不够。这很显然是一道01背包的变形所以只要稍稍的把01背包的转移方程改一下即可,

f[j]=f[j]+f[j-w[i]];初始化f[0]=1;这样加上一些小细节这道题就可以被轻松a掉。

代码:

#include<ctime>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdio>
#include<iomanip>
#include<map>
#include<queue>
#include<stack>
#include<cstring>
#include<string>
#include<vector>
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
const int maxn=1002;
int a[7]={0,1,2,3,5,10,20};
int w[maxn],f[maxn],n=0,m=0,ans=0;
int main()
{
    //freopen("1.in","r",stdin);
    for(int i=1;i<=6;i++)
    {
        int x;
        x=read();
        for(int j=1;j<=x;j++)
        {
            w[++n]=a[i];
            m+=a[i];
        }
    }
    f[0]=1;
    for(int i=1;i<=n;i++)
    {
        for(int j=m;j>=w[i];j--)
        {
            f[j]=f[j]+f[j-w[i]];//从i个数中来选和为j的有多少种方案
        }
    }
    for(int i=1;i<=m;i++)
    {
        if(f[i]!=0)ans++;
    }
    printf("Total=%d\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/chdy/p/9734254.html

时间: 2024-11-11 16:29:35

完全背包——01背包方法数的相关文章

HDU1864_最大报销额(背包/01背包)

解题报告 题目传送门 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define inf 99999999 using namespace std; int v,w[35],d[4],dw1,sum,dp[31*1000*100]; int main() { double Q,dw; int n,i,j,m,t; char c; while(~sc

HDU2602_Bone Collector(背包/01背包)

解题报告 题目传送门 题意: 容量为v的大小,物品数n,每个物品有价值和容量,求能装进包的最大价值. 思路: 基础01背包. dp[j]=max(dp[j],dp[j-c[i]]+w[i]) #include <iostream> #include <cstring> #include <cstdio> #define inf 99999999 using namespace std; int main() { int t,i,j,n,v,w[1010],c[1010]

HDU 3591 The trouble of Xiaoqian(多重背包+01背包)

HDU 3591 The trouble of Xiaoqian(多重背包+01背包) http://acm.hdu.edu.cn/showproblem.php?pid=3591 题意: 有一个具有n种货币的货币系统, 每种货币的面值为val[i]. 现在小杰手上拿着num[1],num[2],-num[n]个第1种,第2种-第n种货币去买价值为T(T<=20000)的商品, 他给售货员总价值>=T的货币,然后售货员(可能,如果小杰给的钱>T, 那肯定找钱)找钱给他. 售货员每次总是用

动态规划-01背包

先认错,学长们很早之前就讲过了,然而我现在才来写... 01背包 01背包是在M件物品取出若干件放在空间为W的背包里,每件物品的体积为W1,W2--Wn,与之相对应的价值为P1,P2--Pn. 01背包题目的雏形是: 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使价值总和最大. 从这个题目中可以看出,01背包的特点就是:每种物品仅有一件,可以选择放或不放. 其状态转移方程是: f[i][v]=max{f[i-1][v],f[i-1][v-c

背包问题-01背包

*/--> 背包问题-01背包 Table of Contents 1 问题描述 2 问题思路 2.1 问题定义 2.2 实例演讲 3 问题思考 3.1 优化-定义问题 3.1.1 索引的改变 3.1.2 顺序的改变 3.2 优化-复杂度 3.3 初始值的思考 4 问题延伸 4.1 01背包问题的其他解法 4.2 01背包问题的实际引用 5 参考阅读 1 问题描述 背包问题主要分为三种:01背包 完全背包 多重背包. 01背包就是本文要讨论的问题. 有N件物品和一个容量为W的背包,每种物品 均只

动态规划之背包问题-01背包+完全背包+多重背包

01背包 有n种不同的物品,每种物品分别有各自的体积 v[i],价值 w[i]  现给一个容量为V的背包,问这个背包最多可装下多少价值的物品. 1 for(int i = 1; i <= n; i++) 2 for(int j = V; j >= v[i]; j--) 3 dp[j] = max(dp[j], dp[j-v[i]]+w[i]); //dp[V]为所求 完全背包 01背包每种物品只能取一个, 完全背包即物品不记件数,可取多件. 1 for(int i = 1; i <= n

背包整理(01背包,完全背包,多重背包,分组背包)(待更新)

目录 01背包 优化(空间) 完全背包 优化 多重背包 优化 分组背包 01背包 有N件物品和一个容量为V的背包.第i件物品的价格(即体积,下同)是w[i],价值是c[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 对于每个物品,我们有两种选择:把这个物品放进背包还是不放. d[i][v]表示前i件物品,恰放入容积为v的背包时的价值总和. 状态转移方程为 \[d[i][v] = \max(d[i - 1][v],d[i - 1][v - w[i]] + c[i

01背包&amp;完全背包

·01背包&完全背包基础 01背包模型:给定n个物品,第i个物品体积为Wi,价值为Vi,背包容量为sum,选择一些物品放入背包,要求总价值最大. F[i,j]表示前i个物品放入容量为j的包里获得的最大价值. 对于任意一个物品都有两种状态,要么放要么不放,不放的话很显然价值同前,放的话就要从包里拿出一部分体积. 完全背包模型:给定n种物品,第i个物品体积为Wi,价值为Vi,背包容量为sum,选择一些物品放入背包,要求总价值最大. F[i,j]表示前i种物品放入容量为j的包里获得的最大价值. 01背

有关货币问题的动态规划题目--有关01背包,完全背包,多重背包

背包dp:参考背包九讲以及给出一些题目 01背包 (先枚举物品,再逆序枚举容量) 给定n件物品和一个容量为V的背包,每件物品的体积是w[i],价值是va[i](1<=i<=n),求在不超过背包的容量的情况下,怎么选择装这些物品使得得到的价值最大? 例如:有5件物品,体积分别是{2,2,6,5,4},价值分别是{6,3,5,4,6} 递归式:F(i,v)=max(F(i-1,v), F(i-1,v-w[i])+va[i]),其中F(i,v)表示把前i种物品恰放入背包容量为v时取得的最大价值 把这