LeeBlog

导航

HDU 1085 Holding Bin-Laden Captive! 母函数||背包||递推

水题  。。  直接把所有可能枚举。。  最后找出没有可能的,即系数为0 的最小数

#include<stdio.h>
#include<string.h>
int s[4] = {0,1,2,5},m1[100000],m2[100000],num[4],max;
void gf(  )
{
     memset( m1,0,sizeof( m1 ) );
     memset( m2,0,sizeof( m1 ) );
     for( int i = 0; i <= num[1]; ++i )
          m1[i] = 1;
     for( int i = 2; i <= 3; ++i )
     {
          for( int j = 0; j <= max; ++j )
               for( int k = 0; k <= num[i]; ++k )
                    m2[j+k*s[i]] += m1[j];
          for( int j = 0; j <= max ; ++j )
               m1[j] = m2[j],m2[j] = 0;
     }
 }
int main( )
{
    while( scanf( "%d%d%d",&num[1],&num[2],&num[3] ),num[1]||num[2]||num[3] )
    {
           int min = 0;
           max = num[1]+num[2]*2+num[3]*5+1;
           gf(  );
           for( int j = 1; j <= max; ++j )
                if( !m1[j] )
                {
                    min = j;
                    break;
                }
           printf( "%d\n",min );
           }
    return 0;
}

下面是一神代码,小晨的神代码,仔细想想 。。 是这么回事额。。 如果1 - 4之间的数都能拼凑起来,那么在sum = n1 + n2 * 2 + n3 *5 之间的数肯定都能拼出来了。。 是吧 。。 因为在sum之间的数都可以表示为5 * n + 0, 5 * n + 1,

5 * n + 2,5 * n + 3, 5 * n + 4,所以只要1,2,3,4能拼出来,那么sum以内的数都能拼出来了,那么最小的那个不能拼出来的就是sum + 1,否则,连1,2,3,4都不能拼出来那么最小的那个不能拼出来的就是1,2,3,4中最小的不能拼出来的那个。

#include<stdio.h>
int main( )
{
    int a,b,c;
    while( scanf( "%d%d%d",&a,&b,&c ),a||b||c )
    {
           if( !a ) puts( "1" );
           else if( a + 2 * b < 4 )
               printf( "%d\n",a + 2 * b + 1 );
           else printf( "%d\n",a + 2 * b + 5 * c + 1 );
           }
    return 0;
}

下面是背包写法,背包的思想是怎样的呢???  其实这个多重背包比较特殊,因为它的重量和价值都是v[i],那么在重量v[i]内如果能装到v[i]的话,那也就说明能够拼出v[i],否则这个肯定拼不出,是吧。。。 哈哈。。

#include<stdio.h>
#include<string.h>
int num[4],sum,v[4] = { 0 , 1, 2 , 5},dp[10000];
inline int max( int a,int b )
{
       return a > b ? a : b;
}
void _01( int v,int w )
{
     for( int j = sum; j >= v; --j )
          dp[j] = max( dp[j-v] + w,dp[j] );
 }
void complete( int v,int w )
{
     for( int j = v; j <= sum; ++j )
          dp[j] = max( dp[j-v] + w,dp[j] );
 }
void multiply( int v,int w,int c )
{
     if( c * v > sum )
         complete( v,w );
     else
     {
         int k = 1;
         while( c > k )
         {
                _01( k * v, k * w );
                c -= k;
                k << 2;
                }
         _01( c * v, c * w );
     }
 }
int main( )
{
    while( scanf( "%d%d%d",&num[1],&num[2],&num[3] ),num[1]|num[2]|num[3] )
    {
           memset( dp,0,sizeof( dp ) );
           sum = num[1] + 2 * num[2] + num[3] * 5;
           for( int i = 1; i <= 3; ++i )
                multiply( v[i],v[i],num[i] );
           int c = 0;
           for( int i = 1; i <= sum; ++i )
                if( dp[i] != i )//这里就是找最小值
                {//找到不能拼出来的那个数
                    c = i;
                    break;
                }
           if( !c )
               c = sum + 1;
           printf( "%d\n",c );
           }
    return 0;
}

posted on 2011-05-12 10:37  LeeBlog  阅读(172)  评论(0编辑  收藏  举报