背包方案问题

随笔 - 766  文章 - 1  评论 - 107

.背包问题方案总数

  对于一个给定了背包容量、物品费用、物品间相互关系(分组、依赖等)的背包问题,除了再给定每个物品的价值后求可得到的最大价值外,还可以得到装满背包或将背包装至某一指定容量的方案总数。

  对于这类改变问法的问题,一般只需将状态转移方程中的max改成sum即可。例如若每件物品均是01背包中的物品,转移方程即为f[i][v]=sum{f[i-1][v],f[i-1][v-w[i]]+c[i]},初始条件f[0][0]=1。

  事实上,这样做可行的原因在于状态转移方程已经考察了所有可能的背包组成方案。

货币系统

【问题描述】

  给你一个n种面值的货币系统,求组成面值为m的货币有多少种方案。样例:设n=3,m=10,要求输入和输出的格式如下:

【样例输入】money.in

3  10                                //3种面值组成面值为10的方案

1                                      //面值1

2                                      //面值2

5                                      //面值5

【样例输出】money.out

  10                             //有10种方案

算法
设f[j]表示面值为j的最大方案数, 如果f[j-k*a[i]]!=0则f[j]=f[j]+f[j-k*a[i]],当1<=i<=n,m>=j>= a[i],1<=k<=j / a[i]。
#include<cstdio>
int m, n;
int a[1001];
long long f[10001];
int main()
{
    scanf("%d%d",&n,&m);
    for (int i = 1; i <= n; i++)
       scanf("%d",&a[i]);
    f[0] = 1;
    for (int i = 1; i <= n; i++)
        for (int j = m; j >= a[i]; j--)
            for (int k = 1; k <= j / a[i]; k++)
                f[j] += f[j-k*a[i]];
    printf("%lld",f[m]);
    return 0;
}

【算法分析2】
  设f[j]表示面值为j的总方案数,如果f[j-a[i]]!=0则f[j]=f[j]+f[j-a[i]],1<=i<=n,a[i]<=j<=m。
【参考程序2】
#include<cstdio>
using namespace std;

int n, m;
int a[101];
long long f[10001];            

int main(){
    scanf("%d%d",&n,&m);
    for (int i = 1; i <= n; i++)
       scanf("%d",&a[i]);
    f[0] = 1;
    for (int i = 1; i <= n; i++)
       for (int j = a[i]; j <= m; j++)
          f[j] += f[j-a[i]];
    printf("%lld",f[m]);
    return 0;
}

题目背景

uim神犇拿到了uoi的ra(镭牌)后,立刻拉着基友小A到了一家……餐馆,很低端的那种。

uim指着墙上的价目表(太低级了没有菜单),说:“随便点”。

题目描述

不过uim由于买了一些辅(e)辅(ro)书,口袋里只剩M元(M<=10000)。

餐馆虽低端,但是菜品种类不少,有N种(N<=100),第i种卖ai元(ai<=1000)。由于是很低端的餐馆,所以每种菜只有一份。

小A奉行“不把钱吃光不罢休”,所以他点单一定刚好吧uim身上所有钱花完。他想知道有多少种点菜方法。

由于小A肚子太饿,所以最多只能等待1秒。

输入输出格式

输入格式:

第一行是两个数字,表示N和M。

第二行起N个正数ai(可以有相同的数字,每个数字均在1000以内)。

输出格式:

一个正整数,表示点菜方案数,保证答案的范围在int之内。

输入输出样例

输入样例#1:
复制

4 4
1 1 2 2

输出样例#1: 复制

3

#include<iostream>
using namespace std;
int dp[10002];
int c[102];

int main()
{
    int n,v;
    cin>>n>>v;
    for(int i=1;i<=n;i++)   cin>>c[i];
        dp[0]=1;
    for(int i=1;i<=n;i++)
    {
        for(int j=v;j>=c[i];j--)
            dp[j]+=dp[j-c[i]];
    }
    cout<<dp[v]<<endl;
}



原文地址:https://www.cnblogs.com/damaoranran/p/9053932.html

时间: 2024-11-06 09:50:33

背包方案问题的相关文章

HDU 1284 钱币兑换问题 (动态规划 背包方案数)

钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 15134    Accepted Submission(s): 9117 Problem Description 在一个国家仅有1分,2分,3分硬币,将钱N兑换成硬币有很多种兑法.请你编程序计算出共有多少种兑法. Input 每行只有一个正整数N,N小于32768. Outp

背包方案

对于一个给定了背包容量.物品费用.物品间相互关系(分组.依赖等)的背包问题, 除了再给定每个物品的价值后求可得到的最大价值外,还可以得到装满背包或将背包装至某一指定容量的方案总数. 对于这类改变问法的问题,一般只需将状态转移方程中的max改成sum即可. 例如若每件物品均是01背包中的物品, 转移方程即为f[i][v]=sum{f[i-1][v],f[i-1][v-w[i]]+c[i]},初始条件f[0][0]=1. [例8].货币系统 [问题描述] 给你一个n种面值的货币系统,求组成面值为m的

UVa 11137 (完全背包方案数) Ingenuous Cubrency

题意:用13.23……k3这些数加起来组成n,输出总方案数 d(i, j)表示前i个数构成j的方案数则有 d(i, j) = d(i-1, j) + d(i, j - i3) 可以像01背包那样用滚动数组来实现 1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 using namespace std; 6 7 const int maxn = 10; 8

01背包方案数(变种题)Stone game--The Preliminary Contest for ICPC Asia Shanghai 2019

题意:https://nanti.jisuanke.com/t/41420 给你n个石子的重量,要求满足(Sum<=2*sum<=Sum+min)的方案数,min是你手里的最小值. 思路: 从最大重量的石子开始背包,每次ans+=dp[j-v[i]]就行了. 1 #define IOS ios_base::sync_with_stdio(0); cin.tie(0); 2 #include <cstdio>//sprintf islower isupper 3 #include &

NOIP2012pj摆花[DP 多重背包方案数]

题目描述 小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共m盆.通过调查顾客的喜好,小明列出了顾客最喜欢的n种花,从1到n标号.为了在门口展出更多种花,规定第i种花不能超过ai盆,摆花时同一种花放在一起,且不同种类的花需按标号的从小到大的顺序依次摆列. 试编程计算,一共有多少种不同的摆花方案. 输入输出格式 输入格式: 第一行包含两个正整数n和m,中间用一个空格隔开. 第二行有n个整数,每两个整数之间用一个空格隔开,依次表示a1.a2.……an. 输出格式: 输出只有一行,一个整数

bzoj1708[Usaco2007 Oct]Money奶牛的硬币(背包方案数dp)

1708: [Usaco2007 Oct]Money奶牛的硬币 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 763  Solved: 511[Submit][Status][Discuss] Description 在创立了她们自己的政权之后,奶牛们决定推广新的货币系统.在强烈的叛逆心理的驱使下,她们准备使用奇怪的面值.在传统的货币系统中,硬币的面值通常是1,5,10,20或25,50,以及100单位的货币,有时为了更方便地交易,会发行面值为2单位

洛谷 P1064 金明的预算方案【DP/01背包-方案数】

题目背景 uim神犇拿到了uoi的ra(镭牌)后,立刻拉着基友小A到了一家--餐馆,很低端的那种. uim指着墙上的价目表(太低级了没有菜单),说:"随便点". 题目描述 不过uim由于买了一些辅(e)辅(ro)书,口袋里只剩M元(M<=10000). 餐馆虽低端,但是菜品种类不少,有N种(N<=100),第i种卖ai元(ai<=1000).由于是很低端的餐馆,所以每种菜只有一份. 小A奉行"不把钱吃光不罢休",所以他点单一定刚好吧uim身上所有钱

hdu2126---Buy the souvenirs(01背包方案数)

Problem Description When the winter holiday comes, a lot of people will have a trip. Generally, there are a lot of souvenirs to sell, and sometimes the travelers will buy some ones with pleasure. Not only can they give the souvenirs to their friends

完全背包——方案个数 UVA11137 Ingenuous Cubrency

题目描述如下 : 代码如下: #include <stdio.h> unsigned long long int dp[10001] ; int main (){ int i,j ,k ; int v[22]; int n ; for (i = 1 ; i < 22 ; i ++) v[i] = i*i*i ; dp [0] = 0 ; for ( i = 1 ; i <=21 ; i ++ ){ for ( j = 0 ; j<10001 ; j ++ ){ if ( j&