735 3 4 125 6 5 3 350 //735的最大额,3种,4个125,6个5,3个350
633 4 500 30 6 100 1 5 0 1
735 0
0 3 10 100 10 50 10 10
735
630
0
0
1 #include<cstdio>
2 #include<iostream>
3 #include<algorithm>
4 #include<cstring>
5 #include<cmath>
6 #include<queue>
7 using namespace std;
8 const int maxn=100005;
9 int n,m,t;
10 int dp[maxn],w[maxn],v[maxn];
11 int nValue;
12 //0-1背包,代价为cost,获得的价值为weight
13 void ZeroOnePack(int cost,int weight)
14 {
15 for(int i=nValue;i>=cost;i--)
16 dp[i]=max(dp[i],dp[i-cost]+weight);
17 }
18
19 //完全背包,代价为cost,获得的价值为weight
20 void CompletePack(int cost,int weight)
21 {
22 for(int i=cost;i<=nValue;i++)
23 dp[i]=max(dp[i],dp[i-cost]+weight);
24 }
25
26 //多重背包
27 void MultiplePack(int cost,int weight,int amount)
28 {
29 if(cost*amount>=nValue) CompletePack(cost,weight);
30 else
31 {
32 int k=1;
33 while(k<amount)
34 {
35 ZeroOnePack(k*cost,k*weight);
36 amount-=k;
37 k<<=1;
38 }
39 ZeroOnePack(amount*cost,amount*weight);//这个不要忘记了,经常掉了
40 }
41 }
42 int main()
43 {
44 int i,j,k;
45 #ifndef ONLINE_JUDGE
46 freopen("1.in","r",stdin);
47 #endif
48 while(scanf("%d%d",&nValue,&n)!=EOF)
49 {
50 for(i=0;i<n;i++)
51 {
52 scanf("%d%d",&w[i],&v[i]);
53 }
54 memset(dp,0,sizeof(dp));
55 for(i=0;i<n;i++)
56 {
57 MultiplePack(v[i],v[i],w[i]);
58 }
59 printf("%d\n",dp[nValue]);
60 }
61 }