ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【归纳】dp学习之路

2021-05-24 12:52:09  阅读:161  来源: 互联网

标签:归纳 int ll 样例 学习 lld dp define


完全背包(循环体)模板

for(i=0;i<数量;i++)
{
       for(j=容量;j>=体积[i];j++)
       {
            dp[j]=max(dp[j],dp[j-单件物品体积[i]]+单间物品价值[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\n",s);
}

 

 

P1757 通天之分组背包

 

 样例:

 输入      输出

45 3       10
10 10 1
10 5 1
50 400 2

 

 

 

 

 

 

 

 









标签:归纳,int,ll,样例,学习,lld,dp,define
来源: https://blog.51cto.com/u_15220686/2806817

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有