题目链接:
HDU 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活
题意:
有m元资金和n种大米,每种大米每袋的价格是
price[i]
,每袋的重量是
weight[i]
,袋数是
num[i]
袋,问由这m元资金最多可以买到的大米的重量是多少?m元可以不用完。
分析:
多重背包。
用dp[i][j]表示在前i种大米中用j元最多可以买到的大米的重量。
初始化:dp全为0。
状态转移方程:
dp[i][j]=max(dp[i][j],dp[i-1][j-k*price[i]]+k*weight[i]);
其中k指第i种大米买k袋。
注意:
k的枚举范围是从0开始!并且k<=num[i]&&k*price[i]<=j
!
//1456K 15MS
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX_N=110;
int T,n,m;
int price[MAX_N],weight[MAX_N],num[MAX_N],dp[MAX_N][MAX_N];
int main()
{
freopen("hdu2191in.txt","r",stdin);
scanf("%d",&T);
while(T--){
scanf("%d%d",&m,&n);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&price[i],&weight[i],&num[i]);
}
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
for(int k=0;k<=num[i]&&k*price[i]<=j;k++){
dp[i][j]=max(dp[i][j],dp[i-1][j-k*price[i]]+k*weight[i]);
}
}
}
printf("%d\n",dp[n][m]);
}
return 0;
}