01 完全 多重 混合 二维 分组 背包模板


void
zero(int w,int v)//01 { for(int i=m;i>=w;i--)dp[i]=max(dp[i],dp[i-w]+v); } void com(int w,int v)//完全 { for(int i=w;i<=m;i++)dp[i]=max(dp[i],dp[i-w]+v); } void multi(int w,int v,int c)//多重(可看成完全和01组成/混合又可看成它们3种组成 { if(c*w>=m) { com(w,v); return; } int k=1; while(k<c)//二进制优化 例题tzoj 5736 { zero(k*w,k*v); c=c-k; k=k*2; } zero(c*w,c*v); }

01背包 (取或不取这件)
      int n,i,j,m,w[35],v[35],dp[205];// 最多30个物品,最大容量m=200
      cin>>m>>n;
      for(i=1;i<=n;i++)cin>>w[i]>>v[i];//重量,价值 
      for(i=1;i<=n;i++)
            for(j=m;j>=w[i];j--)//逆序 
                   dp[j]=max(dp[j-w[i]]+v[i],dp[j]);
      cout<<dp[m]<<endl;

void ZeroOnePack()//dp【x】:表示 和为x的方案数
{
    memset(dp,0,sizeof(dp));
    dp[0]=1;
    for(int i=0;i<n;i++){
        for(int j=maxS-1;j>=s[i];j--){
            dp[j]+=dp[j-s[i]];
        }
    }
}
完全背包(一件东西有无限件,可以取无限次)
      int n,m,i,j,w[32],c[32],dp[202]; 
      scanf("%d%d",&m,&n);//容量,种数 
      for(i=1;i<=n;i++)cin>>w[i]>>v[i];//重量,价值 
      for(i=1;i<=n;i++)
                for(j=w[i];j<=m;j++)
                    dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
      printf("max=%d",dp[m]);
 多重背包:(toj 5740)
       for(i=1;i<=n;i++)
            for(k=0;k<mun[i];k++)//每种的个数   (attention  没有等于号)
                for(j=m;j>=w[i];j--) dp[j]=max(dp[j],dp[j-w[i]]+v[i]);


二维费用流背包:(toj 5742)
注意if 和 初始化 和 到0
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f 
int n,m,k,a[1005],b[1005],w[1005],dp[22][80];
int main()
{
    int i,j,q;
    cin>>m>>n;
    cin>>k;
    for(i=1;i<=k;i++)cin>>a[i]>>b[i]>>w[i];
    for(i=0;i<=m;i++)
       for(j=0;j<=n;j++)dp[i][j]=INF;//刚好装满 
    dp[0][0]=0;
    for(i=1;i<=k;i++)
       for(j=m;j>=0;j--)//注意要到0 /////////////////////////////////
          for(q=n;q>=0;q--)
          {
                int t1=j-a[i],t2=q-b[i];////////////////注意这些if语句
                if(t1>m)t1=m;
                if(t2>n)t2=n;
                if(t1<0)t1=0;
                if(t2<0)t2=0;
                dp[j][q]=min(dp[j][q],dp[t1][t2]+w[i]);
          }
    cout<<dp[m][n]<<endl;  
 }  
View Code

   

分组背包:(toj 5743)

#include<bits/stdc++.h>
using namespace std;
int n,V,t,w[31],c[31],a[11][31],dp[202];
int main()
{
    int i,j,k;
    cin>>V>>n>>t;
    for(i=1;i<=n;i++)
    {
        int p;
        cin>>w[i]>>c[i]>>p;
        a[p][++a[p][0]]=i; //a[p][0]存储p组元素个数,a[p][x] 是存储元素序号
    }//a[p][x] p组第x个 
    for(i=1;i<=t;i++)
    {
        for(j=V;j>=0;j--)
        {
            for(k=1;k<=a[i][0];k++)
            {
                int te=a[i][k];
                if(j>=w[te])dp[j]=max(dp[j],dp[j-w[te]]+c[te]);
            }
         } 
    }
    cout<<dp[V]<<endl;
}
View Code
 

混合背包链接 https://www.cnblogs.com/Surprisezang/p/9128018.html

猜你喜欢

转载自www.cnblogs.com/ydw--/p/10914952.html