/*
01背包问题 一个物体只能选一次 0就是不选,1就是选
完全背包问题 每一个物体选的次数不限
多重背包问题 每个物体选的上限是不同的,而且是有限制的
混合背包问题 有多种背包,给出每个信息
二维费用的背包问题 除了体积之外,还有重量的规定
分组背包问题 组内之间的物体相互之间是互斥的 把各种各样的物体都分成若干组,每一组中选出一个来,
背包问题求方案数 求最小值,求方案数
求背包问题的方案
有依赖的背包问题 比如选课,修概率论,你还必须得修数学
f[i][j] 表示只看前i个物品,总体积是j的情况下,总价值最大是多少
result= max[f[n][0-v]]
f[i][j]
1.不选第i个物品,f[i][j]=f[i-1][j];
2.选第i个物品,f[i][j]=f[i-1][j-v[i]];
f[i][j]=max(1,2);
f[0][0]=0;
*/
/*
问题描述:
有N件物品和一个容量是V的背包
第i件物品的体积是vi,价值是wi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。
输入:
第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。
接下来有N行,每行两个整数vi,wi,用空格隔开,分别表示第i件物品的体积和价值。
输出:
输出一个整数,表示最大价值
*/
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1010;
int n,m; //n表示物品个数,m表示物体容量
//int f[N][N];
int f[N];
int v[N],w[N];//每个物体的体积和价值
//定到全局变量,全局变量是在堆里面的,堆里面数据初始化为0,所以 f[0][0]=0
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++) cin>>v[i]>>w[i];
//从前往后枚举所有的体积
for(int i=1;i<=n;i++)
//for(int j=0;j<=m;j++)
for(int j=m;j>=v[i];j--) //直接把下面判断条件融入
// {
// f[i][j]=f[i-1][j];//第一个物体不选的话
// 第i层只和第i-1层有关,代码进行优化 ,没有必要把所有的一层都计算
//可以使用滚动数组,也可以把二维优化成一维;
//if(j>=v[i])
// f[i][j]=max(f[i][j],f[i-1][j-v[i]]+w[i]);
f[j]=max(f[j],f[j-v[i]]+w[i]);
// j-v[i]匹配i-1状态
// }
// int res=0;
// for(int i=0;i<=m;i++)
// res=max(res,f[n][i]);
// cout<<res<<endl;
/*
如果只把f[0]初始化为0,其他的初始化为负无穷
如果把f[i]=0
k<m
f[k]=max_w;
*/
cout<<f[m]<<endl;
return 0;
}