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;
}
posted @ 2016-08-17 23:29  see_you_later  阅读(95)  评论(0编辑  收藏  举报