HDU 2844 Coins 多重背包
这题看着我第一感觉是母函数,但是据说母函数会TLE,就果断多重背包了,而这里用多重背包做,明显不能直接把dp[n]输出来,那样结果是错的,那怎么才能找到种类呢。if( dp[i] ) ++c;??????这样行吗???? 不行,这是后要想到dp[i]的含义,dp[i]代表着在重量i时能找到的最大价值,而这里的重量和价值都是钱,所以就有很方便的一个地方了,dp[i]中最多能装下i的话那么肯定i能够选到,所以就有判断条件了if( dp[i] == i ) ++c;
直接上代码吧
#include<stdio.h>
#include<string.h>
//#define max( a , b ) ( a ) > ( b ) ? ( a ) : b
int n,m,v[105],w[105],num[105],dp[100005];
inline int max( int a,int b )//记得加内联,这样要快很多很多
{
return a > b ? a : b;
}
void _01( int v, int w )
{
for( int j = m; j >= v; --j )
dp[j] = max( dp[j-v] + w, dp[j] );
}
void complete( int v,int w )
{
for( int j = v; j <= m; ++j )
dp[j] = max( dp[j-v] + w, dp[j] );
}
void multiply( int v,int w,int c )
{
if( v * c > m )
complete( v,w );
else
{
int k = 1;
while( c > k )
{
_01( k * v, k * w );
c -= k;
k <<= 1;
}
_01( c * v, c * w );
}
}
int main( )
{
while( scanf( "%d%d",&n,&m ),n|m )
{
for( int i = 1; i <= n; ++i )
scanf( "%d",&v[i] );
for( int i = 1; i <= n; ++i )
scanf( "%d",&num[i] );
memset( dp,0,sizeof( dp ) );
for( int i = 1; i <= n; ++i )
multiply( v[i],v[i],num[i] );
int c = 0;
for( int i = 1; i <= m; ++i )
if( dp[i] == i )
++c;
printf( "%d\n",c );
}
return 0;
}
本人还是新手 ,转载请注明来自Lvsi‘s home
浙公网安备 33010602011771号