poj1276——cash machine

前情提要:

<0-1背包>n个物品,背包容量为C,每个物品容积为w[i],每个物品价值为v[i],求将哪些物品放入背包不超过背包容积,且价值最大

              状态为dp[i][j],表示考虑选择第i...到n个物品,容量为j时的最大价值              

              转移方程为dp[i][j]=max{dp[i+1][j],dp[i+1][j-w[i]]+v[i]}(当w[i]<=j时)

                                        =dp[i+1][j](当w[i]>j时)

              结果为dp[1][C]

<完全背包>区别在于每个物品的个数无上限,也就是说不是放与不放两种情况,而是放0,1,2...多少个

                转移方程为dp[i][j]=max{dp[i+1][j],dp[i+1][j-k*w[i]]+k*v[i]},0<=k*w[i]<=j

                                          =dp[i+1][j],k*w[i]>j

<多重背包问题>区别在于每个物品的个数为指定的n[i]个,也就是第i个物品数量为n[i]

                      转移方程为dp[i][j]=max{dp[i+1][j],dp[i+1][j-k*w[i]]+k*v[i]},0<=k<=n[i],0<=k*w[i]<=j

                                          =dp[i+1][j],k*w[i]>j

题目大意:要取定额为cash的钱,有n种面额的钱,面额为b[i]的钱有a[i]张,求能提供的最接近并不超过要取金额的数值

输入:cash N  n1  D1  n2  D2...

          735  3  4  125  6  5  3  350

输出:所求数值

分析:典型的多重背包问题,n种纸币(物品),每种面额(重量)为b[i]的纸币(物品)有a[i]张(个)。在这个问题中,单个物品的价值等于它的重量(面值)。

dp[i]=1表示能达到总额i

代码:转载自https://blog.csdn.net/libin56842/article/details/9473019

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
 
struct node
{
    int n,v;
} a[20];
 
int dp[100010];
 
int main()
{
    int sum,n,i,j,k;
    while(~scanf("%d%d",&sum,&n))
    {
        for(i = 1; i<=n; i++)
            scanf("%d%d",&a[i].n,&a[i].v);
        memset(dp,0,sizeof(dp));
        dp[0] = 1;
        int MAX = 0,tem;
        for(i = 1; i<=n; i++)
        {
            for(j = MAX;j>=0;j--)
            {
                if(dp[j])
                {
                    for(k = 1;k<=a[i].n;k++)
                    {
                        tem = j+k*a[i].v;
                        if(tem>sum)
                            break;
                        dp[tem] = 1;
                        if(tem>MAX)
                        MAX = tem;
                    }
                }
            }
        }
        printf("%d\n",MAX);
    }
 
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值