背包 模版

01背包  



n代表物品种数,c[]代表花费,val[]代表价值  num[]代表 数量

for(i=1;i<=n;i++)

{

    for(j=v;j>=c[i];j--)

      dp[j]=max(dp[j],dp[j-c[i]]+val[i]);

}



多重背包



 for(i=1;i<=m;i++)

        {

            for(j=1;j<=num[i];j++)

            {

                for(k=n;k>=w[i];k--)

                dp[k]=max(dp[k],dp[k-w[i]]+val[i]);

            }

        }


第二种
 1 for( i = ;i<= m; ++i)

 2 {

 3     for( j = V ;j >= v[i]; --j)

 4     {

 5         for( k = 0; k <= num[i] ;k++)

 6         {

 7             vsum = k*val[i];

 8             wsum = k*v[i];

 9             if( wsum > V) break;

10             else 

11             {

12                 f[i] = max(f[i],f[ i - wsum] + vsum);

13             }

14         }

15     }

16 }

 

完全背包



for(i=1;i<=n;i++)

{

    for(j=c[i];j<=v;j++)

      dp[j]=max(dp[j],dp[j-c[i]]+val[i]);

}

  


多重背包的二进制优化

http://poj.org/problem?id=1276

#include<iostream>

#include<stdio.h>

#include<string.h>

const int N=120005;

using namespace std;

int v,n,num[N],val[N],dp[N];

void zeropack(int c)

{

    for(int i=v;i>=c;i--)

     dp[i]=max(dp[i],dp[i-c]+c);

}

void completepack(int c)

{

    for(int i=c;i<=v;i++)

       dp[i]=max(dp[i],dp[i-c]+c);

}

void multipack(int c,int num)

{

    if(c*num>=v)

       completepack(c);

       else

       {

           int k=1;

           while(k<num)

           {

               zeropack(k*c);

               num-=k;



               k*=2;



           }

           zeropack(num*c);

       }



}

int main()

{

      int i;

    while(scanf("%d%d",&v,&n)!=EOF)

    {



        int flag=0;

        memset(dp,0,sizeof(dp));

        for(i=0;i<n;i++)

        {

            scanf("%d%d",&num[i],&val[i]);

            if(val[i]==v){dp[v]=v;flag=1;}

        }

        if(v==0){dp[v]=0;flag=1;}

        if(!flag)

        {

            for(i=0;i<n;i++)

            {

                if(num[i]&&val[i]<=v)multipack(val[i],num[i]);

            }

        }

        printf("%d\n",dp[v]);

    }



}

  

  

你可能感兴趣的:(模版)