Greedy big mouth multiple backpack dp

7-4 Greedy Big Mouth (15 points)
There is a very greedy big mouth, she likes to eat a small cake, and each small cake has a deliciousness, and the big mouth is very arrogant, must To eat small cakes that are delicious and just m, and the big mouth is very lazy, she hopes to achieve this goal by eating the smallest number of small cakes. So she hopes that you can design a program to help her decide which small cakes to eat.

Input format:
First enter a line containing 2 integers m and n, which means that the big mouth needs to eat small cakes with deliciousness and m, and there are n types of small cakes. Enter n lines below, each line with 2 integers, the first one Indicates the deliciousness of this kind of small cakes, and the second one indicates the total number of this kind of small cakes in the cake shop

Output format: The
output line contains an integer indicating the minimum number of small cakes that Big Mouth needs to eat. If Big Mouth cannot reach the sum of m's deliciousness by eating small cakes, it will output "><".

Input sample:
Here is a set of input. E.g:

10 2
4 1
2 10
Output sample:
Here is the corresponding output. E.g:

4
Input example:
A set of input is given here. E.g:

10 2
4 1
7 3
Output sample:
Here is the corresponding output. E.g:

<

Solution: This is a problem of multiple knapsacks.
Two solutions The
first one
is represented by dp, the least amount of cake pieces eaten when the deliciousness is i.
Then his transfer equation is dp[k]=min(dp[k],dp[kv[i]]+1);
there are a total of three cycles, representing the number of types of cakes, the number of each type of cake and the corresponding deliciousness The least number of cakes eaten at a degree.
code show as below:

#include <bits/stdc++.h>
#include <algorithm>
#include<iostream>
#include <stdio.h>
#define INF 0x3f3f3f3f
const int maxn=500005;
using namespace std;
typedef long long ll;
int dp[maxn];
int a[maxn];
int v[maxn];
int main(){
    
    
    int m,n,t,va;
    cin>>m>>n;
    memset(dp,INF,sizeof(dp));
    for(int i=1;i<=n;i++){
    
    
        cin>>va>>t;
        //dp[va]=1;
    /*
        for(int k=1;k<=t;k++){
            a[s+k]=v;
        }
        s+=t;*/
        v[i]=va;
        a[i]=t;
    }
    //cout<<s<<endl;;
    dp[0]=0;
    for(int i=1;i<=n;i++){
    
    
        for(int j=1;j<=a[i];j++){
    
    
            for(int k=m;k>=v[i];k--){
    
    
               if(k-v[i]>=0){
    
    
                    //dp[i-a[j]*k]=k;
                    dp[k]=min(dp[k],dp[k-v[i]]+1);
                }
                //if(k-a[i]==0)
                   //f=1;
                //cout<<"i="<<k<<"dp[i]="<<dp[k]<<endl;
            }
        }
    }
    if(dp[m]!=INF)
        cout<<dp[m]<<endl;
    else
        cout<<"><"<<endl;
    return 0;
}

The second method: convert this multiple backpack into a normal 0-1 backpack. If there are multiple backpacks of the same type, you only need to take out the cakes of the same type one by one, and the model at this time becomes One of the simplest 0-1 backpack.
Code

#include <bits/stdc++.h>
#include <algorithm>
#include<iostream>
#include <stdio.h>
#define INF 0x3f3f3f3f
const int maxn=500005;
using namespace std;
typedef long long ll;
int dp[maxn];
int a[maxn];
int v[maxn];
int main(){
    
    
    int m,n,t,va;
    cin>>m>>n;
    memset(dp,INF,sizeof(dp));
    int s=0;
    for(int i=1;i<=n;i++){
    
    
        cin>>va>>t;
        //dp[va]=1;
        for(int k=1;k<=t;k++){
    
    
            a[s+k]=va;
        }
        s+=t;
    }
    //cout<<s<<endl;
    dp[0]=0;
    for(int i=1;i<=s;i++){
    
    
        for(int j=m;j>=a[i];j--){
    
    
            dp[j]=min(dp[j],dp[j-a[i]]+1);

        }
    }
    if(dp[m]!=INF)
        cout<<dp[m]<<endl;
    else
        cout<<"><"<<endl;
    return 0;
}

Guess you like

Origin blog.csdn.net/u011612364/article/details/108908591