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