题目http://poj.org/problem?id=1276
分析 这是一个多重背包的问题,可以把请求的金额当作背包的重量,而货币的面值就是价值又是重量。
于是这个问题便很好理解背包了。
#include<stdio.h>
#include<string.h>
int dp[100010];
int cash;
//01背包
void ZeroOnePack(int cost,int weight)
{
for(int j=cash;j>=cost;j--)
dp[j]=dp[j]>dp[j-cost]+weight?dp[j]:dp[j-cost]+weight;
}
//完全背包
void CompletePack(int cost,int weight)
{
for(int j=cost;j<=cash;j++)
dp[j]=dp[j]>dp[j-cost]+weight?dp[j]:dp[j-cost]+weight;
}
void MultiplePack(int cost,int weight,int amount)
{
if(cost*amount>cash)
{
CompletePack(cost,weight);
}
int k=1;
while (k<=amount)
{
ZeroOnePack(k*cost,k*weight);
amount=amount-k;
k=k*2;
}
ZeroOnePack(amount*cost,amount*weight);
}
int main()
{
int N,n[12],d[12];
while (scanf("%d%d",&cash,&N)!=EOF)
{
for(int i=1;i<=N;i++)
scanf("%d%d",&n[i],&d[i]);
//初始化数据,不需要“装满”
memset(dp,0,sizeof(dp));
//多重背包问题
for(int i=1;i<=N;i++)
MultiplePack(d[i],d[i],n[i]);
printf("%d ",dp[cash]);
}
return 0;
}
#include<string.h>
int dp[100010];
int cash;
//01背包
void ZeroOnePack(int cost,int weight)
{
for(int j=cash;j>=cost;j--)
dp[j]=dp[j]>dp[j-cost]+weight?dp[j]:dp[j-cost]+weight;
}
//完全背包
void CompletePack(int cost,int weight)
{
for(int j=cost;j<=cash;j++)
dp[j]=dp[j]>dp[j-cost]+weight?dp[j]:dp[j-cost]+weight;
}
void MultiplePack(int cost,int weight,int amount)
{
if(cost*amount>cash)
{
CompletePack(cost,weight);
}
int k=1;
while (k<=amount)
{
ZeroOnePack(k*cost,k*weight);
amount=amount-k;
k=k*2;
}
ZeroOnePack(amount*cost,amount*weight);
}
int main()
{
int N,n[12],d[12];
while (scanf("%d%d",&cash,&N)!=EOF)
{
for(int i=1;i<=N;i++)
scanf("%d%d",&n[i],&d[i]);
//初始化数据,不需要“装满”
memset(dp,0,sizeof(dp));
//多重背包问题
for(int i=1;i<=N;i++)
MultiplePack(d[i],d[i],n[i]);
printf("%d ",dp[cash]);
}
return 0;
}