hiho1263 奖券兑换

多重背包,记下拥有同一券同一价值的奖品的数量,当做同一类 P,W<=10,最多10*10=100种

#include<iostream>
#include<string.h>
using namespace std ;
#define MAX 100010
int dp [ MAX ];
int nu [ 20 ][ 20 ];
int n , m ;
struct node
{
int val ; //价值
int cost ; //花费
int num ;
} no [ 110 ];

void zeronepack ( int cost , int val )
{
for ( int i = m ; i >= cost ; i -- )
dp [ i ] = max ( dp [ i ], dp [ i - cost ] + val );
}

void compack ( int cost , int val )
{
for ( int i = cost ; i <= m ; i ++ )
dp [ i ] = max ( dp [ i ], dp [ i - cost ] + val );
}

void multipack ( int cost , int val , int num )
{
if ( cost * num >= m )
compack ( cost , val );
else
{
int k = 1 ;
while ( k < num )
{
zeronepack ( k * cost , k * val );
num -= k ;
k <<= 1 ;
}
zeronepack ( num * cost , num * val );
}
}

int main ()
{
cin >> n >> m ;
int u , v ;
memset ( nu , 0 , sizeof ( nu ));
for ( int i = 0 ; i < n ; i ++ )
{
cin >> u >> v ;
nu [ u ][ v ] ++ ;
}
n = 0 ;
for ( int i = 0 ; i < 110 ; i ++ )
no [ i ]. num = 0 ;
for ( int i = 0 ; i < 11 ; i ++ )
{
for ( int j = 0 ; j < 11 ; j ++ )
{
if ( nu [ i ][ j ])
{
no [ n ]. val = j ;
no [ n ]. cost = i ;
no [ n ++ ]. num = nu [ i ][ j ];
}
}
}
memset ( dp , 0 , sizeof ( dp ));
for ( int i = 0 ; i < n ; i ++ )
{
multipack ( no [ i ]. cost , no [ i ]. val , no [ i ]. num );
}
cout << dp [ m ] << endl ;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值