hdu5410CRB and His Birthday 多重背包

//n个物品 , 容量为m
//每个物品1个占用空间为w
//如果第i个物品选了k(k>0)个,所得权值为k*a+b 
//求最大权值
//多重背包 , 需要用二进制数优化
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std ;
const int maxn = 2010 ;
int dp[maxn][maxn] ;
int main()
{
   // freopen("in.txt" , "r" , stdin) ;
    int t ;
    scanf("%d" , &t) ;
    while(t--)
    {
        memset(dp[0] , 0 , sizeof(dp)) ;
        int n , m ;
        scanf("%d%d" , &m , &n) ;
        for(int i = 1;i <= n;i++)
        {
            int w  ,a , b ;
            scanf("%d%d%d" , &w , &a , &b) ;
            int c = m/w ;
            memcpy(dp[i] , dp[i-1] ,sizeof(dp[i-1])) ;
            for(int k = 1;k <= c ;k *= 2)
            {
                for(int j = m;j >= k*w;j--)
                dp[i][j] = max(dp[i][j] , max(dp[i][j - k*w] + a*k  , dp[i-1][j - k*w] + a*k + b)) ;
                c -= k ;
            }
            if(c)
            for(int j = m ;j >= c*w ;j--)
            dp[i][j] = max(dp[i][j] , max(dp[i][j-c*w] + a*c  , dp[i-1][j - c*w] + a*c + b)) ;
        }
        cout<<dp[n][m]<<endl;
    }
    return 0 ;
}


你可能感兴趣的:(hdu5410CRB and His Birthday 多重背包)