#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m;
int v[10010],w[10010];
int f[10010];
int main()
{
cin>>m>>n;
for(int i=1;i<=n;i++) cin>>v[i]>>w[i];
for(int i=1;i<=n;i++)
for(int j=m;j>=v[i];j--)
f[j] = max(f[j],f[j-v[i]]+w[i]);
cout<<f[m];
return 0;
}
这里顺带说一下优化
首先我们要明白为什么可以从一维变成二维呢?、
是因为我们每次在进行状态转移的时候只会用到上次的状态,体现在网格图中就是下一行的信息仅仅由上一行继承而来
所以我们很容易想到若是每行信息我们都要记录,那是会浪费很多空间的
所以基于实用和偷懒主义,我们就保存一行信息,也就是把二维信息压成一维来记录
但是我们还要考虑更新的顺序,基于01背包的特性——同一件物品是不能被使用超过一次的
所以我们更新信息的时候是不能从小体积开始更新的,因为这样很可能导致后面的状态在继承前面状态的之前这个物品就已经被使用了
所以我们选择把体积从大到小遍历——
这样后面的状态即使是用到前面的状态,也能保证当前这件物品最多被使用一次
要加油哇!!!