Cash Machine POJ - 1276
题目链接:https://vjudge.net/problem/POJ-1276
题意:一个现金机器,有各种种类的现金和对应数量,比如3张100块,5张50块,现在给你这样的输入:
cash N n1 D1 n2 D2 … nN DN, N代表现金种类个数。然后对于ni,Di ,i∈[1,N]表示第i类现金的数量和面值。
问:用这些纸币凑出尽可能多的价值,且价值小于等于cash。
Input
Output
思路:多重背包。输入的ni就是每个物品的数量,Di就是每个物品的重量和价值。用多重背包即可求出不超过cash的最大价值。
代码:
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <cstring>
#define MAX 100007
using namespace std;
int dp[MAX];
int value[MAX],weight[MAX],number[MAX];
int bag;
void ZeroOnePack(int weight,int value )
{
int i;
for(i = bag; i>=weight; i--)
{
dp[i] = max(dp[i],dp[i-weight]+value);
}
}
void CompletePack(int weight,int value)
{
int i;
for(i = weight; i<=bag; i++)
{
dp[i] = max(dp[i],dp[i-weight]+value);
}
}
void MultiplePack(int weight,int value,int number)
{
if(bag<=number*weight)
{
CompletePack(weight,value);
return ;
}
else
{
int k = 1;
while(k<=number)
{
ZeroOnePack(k*weight,k*value);
number = number-k;
k = 2*k;
}
ZeroOnePack(number*weight,number*value);
}
}
int main()
{
int n;
while(cin>>bag)
{
cin>>n;
int i;
for(i = 0; i<=n-1; i++)
{
cin>>number[i]>>weight[i];
value[i]=weight[i];
}
memset(dp,0,sizeof(dp));
for(i = 0; i<=n-1; i++)
{
MultiplePack(weight[i],value[i],number[i]);
}
cout<<dp[bag]<<endl;
}
return 0;
}