CRB and His Birthday
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1655 Accepted Submission(s): 782
Problem Description
Today is CRB's birthday. His mom decided to buy many presents for her lovely son.
She went to the nearest shop withM Won(currency
unit).
At the shop, there areN kinds
of presents.
It costsWi Won
to buy one present of i -th
kind. (So it costs k × Wi Won
to buy k of
them.)
But as the counter of the shop is her friend, the counter will giveAi × x + Bi candies
if she buys x (x >0)
presents of i -th
kind.
She wants to receive maximum candies. Your task is to help her.
1 ≤T ≤
20
1 ≤M ≤
2000
1 ≤N ≤
1000
0 ≤Ai, Bi ≤
2000
1 ≤Wi ≤
2000
She went to the nearest shop with
At the shop, there are
It costs
But as the counter of the shop is her friend, the counter will give
She wants to receive maximum candies. Your task is to help her.
1 ≤
1 ≤
1 ≤
0 ≤
1 ≤
Input
There are multiple test cases. The first line of input contains an integer T ,
indicating the number of test cases. For each test case:
The first line contains two integersM and N .
ThenN lines
follow, i -th
line contains three space separated integers Wi , Ai and Bi .
The first line contains two integers
Then
Output
For each test case, output the maximum candies she can gain.
Sample Input
1 100 2 10 2 1 20 1 1
Sample Output
21HintCRB's mom buys 10 presents of first kind, and receives 2 × 10 + 1 = 21 candies.
题目大意:用m元去买商品,商品有n种,买商品的时候会附加赠送糖果,并且给出了各个商品需要的话费wi元,还有关于赠送糖果量的相关系数ai和bi。随着该物品的购买量x会赠送ai*x+bi个糖果。问,用m元如何购买商品能够获得的最多糖果数目。
解题思路:乍一看就是个完全背包,但是有额外增加的条件。随着购买量增加的赠送的糖果量。bi后面没有涉及到x。所以确定第一个的赠送量就是ai+bi。后面的赠送购买赠送的糖过量就和bi没有关系了,就变成了一个完全背包。刚开始的明显可以通过01背包来解决了。
源代码:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<stack> #include<queue> #include<vector> #include<deque> #include<map> #include<set> #include<algorithm> #include<string> #include<iomanip> #include<cstdlib> #include<cmath> #include<sstream> #include<ctime> using namespace std; int w[1005]; int dp[2005]; int a[1005]; int b[1005]; int main() { int t; int m,n;//m钱款,n代表商品种类数 int i,j; scanf("%d",&t); while(t--) { scanf("%d%d",&m,&n); memset(w,0,sizeof(w)); memset(dp,0,sizeof(dp)); memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); for(i = 0; i < n; i++) { scanf("%d%d%d",&w[i],&a[i],&b[i]); } for(i = 0; i < n; i++) { //先跑一次01背包,这样就不用再考虑bi,因为买与不买都会赠送bi糖果, //0次或者1次考虑完之后,就剩下多次的,再跑完全背包 for(j = m; j >= w[i]; j--) { dp[j]=max(dp[j],dp[j-w[i]]+a[i]+b[i]); } for(j = w[i]; j <= m; j++) { dp[j]=max(dp[j],dp[j-w[i]]+a[i]); } } printf("%d ",dp[m]); } return 0; }