zoukankan      html  css  js  c++  java
  • 算法竞赛模板 动态规划之背包DP

    ① 01背包

    有n件物品和一个容量为v的背包。第i件物品的价值是c[i],体积是w[i]。求解将哪些物品装入背包可使价值总和最大。

    这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        int t,n,v,i,j,w[1005],c[1005],dp[1005];
        cin>>t;
        while(t--)
        {
            memset(dp,0,sizeof dp);
            cin>>n>>v;
            for(i=1;i<=n;i++)
                scanf("%d",&c[i]);
            for(i=1;i<=n;i++)
                scanf("%d",&w[i]);
    for(i=1;i<=n;i++) for(j=v;j>=w[i];j--) dp[j]=max(dp[j],dp[j-w[i]]+c[i]); cout<<dp[v]<<endl; } return 0; }

    ② 完全背包

    有n种物品和一个容量为v的背包,每种物品都有无限件。第i种物品的价值是c[i],体积是w[i]。

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        int t,n,v,i,j,w[1005],c[1005],dp[1005];
        cin>>t;
        while(t--)
        {
            memset(dp,0,sizeof dp);
            cin>>n>>v;
            for(i=1;i<=n;i++)
                scanf("%d",&c[i]);
            for(i=1;i<=n;i++)
                scanf("%d",&w[i]);
                
            for(i=1;i<=n;i++)
                for(j=w[i];j<=v;j++)
                    dp[j]=max(dp[j],dp[j-w[i]]+c[i]); 
            
            cout<<dp[v]<<endl;
        }
        return 0;
    }

    ③ 多重背包

    (1) 有n种物品和一个容量为v的背包。第i种物品最多有num[i]件,每件价值是c[i],体积是w[i]。

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        int t,v,n,i,j,k,dp[105],num[105],c[105],w[105];
        cin>>t;
        while(t--)
        {
            memset(dp,0,sizeof dp);
            cin>>n>>v;
            for(i=1;i<=n;i++)
                scanf("%d%d%d",&c[i],&w[i],&num[i]);
    
            for(i=1;i<=n;i++)
                for(j=1;j<=num[i];j++)
                    for(k=v;k>=w[i];k--)
                        dp[k]=max(dp[k],dp[k-w[i]]+c[i]);
    
            cout<<dp[v]<<endl;
        }
        return 0;
    }

    (2) 2个人平分n种物品第i种物品最多有num[i]件,每件物品价值为c[i],保证两者拥有物品的价值差距最小

    ps:物品总价值÷2,再去做多重背包。

    #include<bits/stdc++.h>
    #define INF 0x3f3f3f3f
    #define MAX 100005
    using namespace std;
    int dp[MAX],c[MAX],num[MAX];
    int main()
    {
        int i,j,k,n,v,vhalf;
        while(scanf("%d",&n)!=EOF)
        {
            memset(dp,0,sizeof(dp));
            v=0;
            for(i=1;i<=n;i++)
            {
                scanf("%d%d",&c[i],&num[i]);
                v+=c[i]*num[i];   //所有物品的总价值 
            }
            vhalf=v/2; 
            for(i=1;i<=n;i++)
                for(j=1;j<=num[i];j++)
                    for(k=vhalf;k>=c[i];k--)
                        dp[k]=max(dp[k],dp[k-c[i]]+c[i]);
                        
            cout<<v-dp[vhalf]<<" "<<dp[vhalf]<<endl;
        }
        return 0;
    }

    ④ 多重背包二进制优化

    有n种船只,每种船只的载货量为w[i],每种船只的数量为2^c[i]-1。接下来有q次询问,每次问有多少种载货方式可以填满容量s,结果取模。

    #include<bits/stdc++.h>
    using namespace std;
    const int MAX=1e4;
    const int mod=1e9+7;
    typedef long long ll;
    int w[25],c[25];
    ll dp[MAX+5];
    int main()
    {
        int n,i,T,q,s,j,k;
        ios::sync_with_stdio(false);
        cin>>T;
        while(T--)
        {
            cin>>n>>q;
            for(i=1;i<=n;i++)
                cin>>w[i]>>c[i];
            memset(dp,0,sizeof(dp));
            dp[0]=1;
            for(i=1;i<=n;i++)       //共n种船
            {
                int t=1;
                for(j=1;j<=c[i];j++)//每种船有2^c[i]-1只
                {
                    for(k=MAX;k>=t*w[i];k--)
                        dp[k]=(dp[k]+dp[k-t*w[i]])%mod;
                    t<<=1;
                }
            }
            while(q--)
            {
                cin>>s;
                cout<<dp[s]<<endl;
            }
        }
        return 0;
    }
  • 相关阅读:
    HDOJ 4259 Double Dealing
    第三课 MongoDB 数据更新
    百度语音识别API初探
    几种常见排序算法的java实现
    HDU 1051 Wooden Sticks 贪心题解
    离线安装Cloudera Manager5.3.4与CDH5.3.4
    Unix哲学
    如何在管理层变动中存活下来
    SWTError: No more handles [gtk_init_check() failed] running platform tests (on Linux)
    "xxadmin" user: No protocol specified 错误
  • 原文地址:https://www.cnblogs.com/kannyi/p/8893942.html
Copyright © 2011-2022 走看看