POJ1276【多重背包】
题意:
给出一个价值sum,然后给出n,代表n个方案,接着n对代表个数与价值,要求最接近sum,但不超过sum的价值。
思路:
多重背包,利用二进制拆分达到保证对于0..n间的每一个整数,均可以用若干个系数的和表示。
贴一发挫code…感受一下
//#include <bits/stdc++.h>
#include<iostream>
#include<string.h>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef __int64 LL;
int c,w;
int co,n;
int dp[110000],t;
int main()
{
while(~scanf("%d%d",&co,&n))
{
int cnt=0;
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++)
{
scanf("%d%d",&c,&w);
int k=1;
if(c==0||w==0) continue;
while(c-k>0)
{
t=k*w;
for(int j=co;j>=t;j--)
dp[j]=max(dp[j],dp[j-t]+t);
c-=k;
k<<=1;
}
t=c*w;
for(int j=co;j>=t;j--)
dp[j]=max(dp[j],dp[j-t]+t);
}
printf("%d\n",dp[co]);
}
return 0;
}