题意:有经费n,有m种大米,大米只能整袋买,每种大米已知每袋重量,每袋的价格及对应的袋数,用有限的经费尽可能的去购买更多的大米。
思路:多重背包+二进制优化
题目给的数据比较小,如果是不优化直接做的话应该也能过,但用了二进制优化后用01背包求解0ms;
所谓的二进制优化:比如有一件物品有10个,每个占空间W, 每个的价值是V。10=1+2+4+3;那样就分解成了4件不同的物品,物品的空间分别为1*W,2*W,4*W,3*W,物品的价值分别是1*V,2*V,4*V,3*V;
背包问题还是推荐看背包九讲(还有背包九讲2.0) 能对背包问题的理解上好几个层次;
代码:
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
int dp[1000];
int v[1000];
int w[1000];
int n,m;
void zeroone(int cost,int v)
{
for(int j=n;j>=cost;j--)
{
dp[j]=max(dp[j],dp[j-cost]+v);
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
while(scanf("%d %d",&n,&m)!=EOF)
{
int cnt=1;
memset(dp,0,sizeof(dp));//初始化
for(int i=1;i<=m;i++)
{
int a,b,c;//价格重量件数
scanf("%d %d %d",&a,&b,&c);
for(int k=1;k<=c;)//二进制优化
{
v[cnt]=k*b;//存储优化过后的数据
w[cnt]=k*a;
c-=k;
k*=2;
cnt++;
}
if(c>0)
{
v[cnt]=c*b;
w[cnt++]=c*a;
}
}
for(int i=1;i<cnt;i++)
{
zeroone(w[i],v[i]);
}
printf("%d\n",dp[n]);
}
}
return 0;
}
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
做完这一题在hdu上面也正式A了200题了。从之前那个什么都不知道只会刷水题的我变成了现在(虽然还是什么都不知道Orz)但至少能做点模板题的我。虽然有了明显的进步但是还是感觉自己好弱。。。当初为什么走上acm的道路,可能就是因为自己的兴趣外加上真心不想让自己大学四年之后好像什么都没有学到,既然自己弱就要好好努力啊。。。新的一学期加油~