• 【归纳】dp学习之路


    完全背包(循环体)模板

    for(i=0;i<数量;i++)
    {
           for(j=容量;j>=体积[i];j++)
           {
                dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
            }
    }

    0-1背包

    【问题描述】

      有1个容量为m的背包,现有n种物品,重量分别为w1,w2…wn,价值分别为v1,v….vn,若每种物品只有1件,求能放入的最大总价值。
    【输入格式】
    第一行:两个整数m(m<=200)和n(n<=30)
    第2~n+1,每行两个整数wi和vi
    【输出格式】
    一个数据,最大总价值
    【输入样例】
    10 4
    2 1
    3 3
    4 5
    7 9
    【输出样例】
    12

    思路

    1、定义dp数组,dp的下标指的是最大重量 dp本身是作为价值的总和 ,当dp的下标值为容量 即为最大值

    2、循环体(很重要)

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define mem(a) memset(a,0,sizeof(a))
    #define sc1(a) scanf("%lld",&a)
    #define sc2(a,b) scanf("%lld%lld",&a,&b)
    #define sc3(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
    const ll MAXN=1e9+7;
    const ll N=1e5+5;
    ll dp[N];
    int main()
    {
        ll m,n,i,j;
        sc2(m,n);
        ll w[n],v[n];
        for(i=0;i<n;i++)
        {
            sc2(w[i],v[i]);
        }
        mem(dp);
        for(i=0;i<n;i++)
        {
            for(j=m;j>=w[i];j--)
            {
                dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
            }
        }
        cout<<dp[m]<<endl;
    }

    P1048 采药

     

     样例:

    输入          输出

    70 3           3
    71 100
    69 1
    1 2
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define mem(a) memset(a,0,sizeof(a))
    #define sc1(a) scanf("%lld",&a)
    #define sc2(a,b) scanf("%lld%lld",&a,&b)
    #define sc3(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
    const ll MAXN=1e9+7;
    const ll N=1e5+5;
    ll dp[N];
    int main()
    {
        ll T,M,i,j;
        sc2(T,M);
        ll t[M],m[M];
        for(i=0;i<M;i++)
        {
            sc2(t[i],m[i]);
        }
        mem(dp);
        for(i=0;i<M;i++)
        {
            for(j=T;j>=t[i];j--)
            {
                dp[j]=max(dp[j],dp[j-t[i]]+m[i]);
            }
        }
        cout<<dp[T]<<endl;
    }

    P1049 装箱问题

     样例:

    输入      输出

    24       0
    6
    8
    3
    12
    7
    9
    7
    #include<bits/stdc++.h>
    using namespace std;
    int dp[100010];
    int main()
    {
        int V,n,i;
        cin>>V>>n;
        int v[n];
        for(i=0;i<n;i++)
        {
            cin>>v[i];
        }
        int j;
        for(i=0;i<n;i++)
        {
            for(j=V;j>=v[i];j--)
            {
                dp[j]=max(dp[j],dp[j-v[i]]+v[i]);
            }
        }
        cout<<V-dp[V]<<endl;
    }

    P2240 【深基12.例1】部分背包问题

     样例:

     输入      输出

    4 50       420.00
    10 60
    20 100
    30 120
    15 45
    #include<bits/stdc++.h>
    using namespace std;
    struct ali
    {
        int m,v;
    };
    bool cmp(ali a,ali b)
    {
        return a.m*b.v<b.m*a.v;         //这样可以避免精度的损失
    }
    int main()
    {
        int i,N,T;
        cin>>N>>T;
        struct ali bag[N];
        for(i=0; i<N; i++)
        {
            cin>>bag[i].m>>bag[i].v;
        }
        sort(bag,bag+N,cmp);
        double s=0;
        for(i=0; i<N; i++)
        {
            if(bag[i].m<=T)
            {
                s+=bag[i].v;
                T-=bag[i].m;
            }
            else
            {
                s=s+(bag[i].v*T*1.0)/bag[i].m;
                break;
            }
        }
        printf("%.2lf
    ",s);
    }

    P1757 通天之分组背包

     样例:

     输入      输出

    45 3       10
    10 10 1
    10 5 1
    50 400 2
    
    
  • 相关阅读:
    Python网络爬虫第三弹《爬取get请求的页面数据》
    18.增量式爬虫
    17.基于scrapy-redis两种形式的分布式爬虫
    关于进程内存磁盘的一些命令
    linux其他命令
    ls -用于显示指定工作目录下之内容(列出目前工作目录所含之文件及子目录)
    mkdir和touch
    ls -列出当前目录下所有的文件或者目录
    cat -用于连接文件并打印到标准输出设备上
    rm -移动文件
  • 原文地址:https://www.cnblogs.com/jackwang-sparrow/p/13371643.html
Copyright © 2020-2023  润新知