完全背包模板题
#include <string>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
struct Node{
int v,num;
}node[110];
int dp[100010],sum;
void ZeroOnePack(int v){//01背包
for(int i=sum; i>=v; i--)
dp[i] = max(dp[i], dp[i - v] + v);
}
void CompletePack(int v){//完全背包
for(int i=v; i<=sum; i++)
dp[i] = max(dp[i], dp[i - v] + v);
}
void MultiplePack(int v, int num){//二进制优化的多重背包
if(v * num >= sum){
CompletePack(v);
return;
}
int k = 1;
while(num > k){
ZeroOnePack(v*k);
num -= k;
k <<= 1;
}
ZeroOnePack(v * num);
}
int main(){
while(scanf("%d",&sum) == 1){
int n;
scanf("%d",&n);
for(int i=0; i<n; i++)
scanf("%d%d",&node[i].num,&node[i].v);
memset(dp, 0, sizeof(dp));
for(int i=0; i<n; i++)
MultiplePack(node[i].v, node[i].num);
int ans = 0;
for(int i=0; i<=sum; i++)
ans = max(ans, dp[i]);
cout << ans << endl;
}
return 0;
}