#include<iostream>
using namespace std;
//比较两个数的大小,返回较大的数
int max(int a,int b)
{
if(a >= b)
return a;
else
return b;
}
//01背包动态规划算法
//C:背包总的容积
//n:物品总数量
//w[]: 存n个物品的重量, v[]:保存n个物品的价值
int KnapSack(int C, int n, int w[], int v[]){
//因为要求 vw[n][C]的值,所以要定义 大小为vw[n+1][C+1]的数组
int vw[n+1][C+1];//容量为C的背包,放n个商品 的最大价值
//定义边界值:背包容量为0时,无法放入商品,所以价值为0
for(int i=0;i<=n;i++){
vw[i][0]=0;
}
//定义边界值:无商品时,无论背包容积多大,价值为0
for(int j = 0; j <= C; j++)
{
vw[0][j] = 0;
}
//从只放1件商品开始,一直到N件商品
for(int i = 1; i <= n; i++)
{
//背包容量从1开始,到最大容量C
for(int j = 1; j <= C; j++)
{
//背包目前的容量小于 第i件商品的重量 ,说明第i件商品放
//不进去
if(j < w[i])
vw[i][j] = vw[i-1][j];
else
vw[i][j] = max(vw[i-1][j], vw[i-1][j-w[i]]+v[i]);
}
}
//定义数组,x[1]=0:表示没有装入第一件商品
// x[1]=1:表示装入第1件商品:
int x[n+1];
int j = C;
for(int i = n ; i >= 0; i--)
{
//表示装入第i件商品后 (装入i物品比不装i物品价值大)
if(vw[i][j] > vw[i-1][j])
{
x[i] = 1;//说明包里面装了i物品
j = j - w[i];//把i物品去掉
}
else
x[i] = 0;
}
return vw[n][C];
}
int main(){
int n;//物品数量 <100
int c;//背包容量
cin>>c;
cin>>n;
int v[100];//保存n个物品的价值
int w[100];// 保存n个物品的重量
//因为下标代表个数,所以从1开始
for(int i=1;i<=n;i++){
cin>>w[i];
cin>>v[i];
}
cout<<KnapSack(c,n,w,v)<<endl;
}
/**************************************************************
Problem: 1282
User: admin
Language: C++
Result: Accepted
Time:74 ms
Memory:9212 kb
****************************************************************/