背包 模版

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]);
    }

}

  

  

posted @ 2012-03-21 17:44  Szz  阅读(156)  评论(0编辑  收藏  举报