【归纳】dp学习之路

完全背包(循环体)模板

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

 

 

 

 

 

 

 

 


posted @ 2020-07-24 15:05  Drophair  阅读(191)  评论(0编辑  收藏  举报