Acwing 背包模型专题打卡

423. 采药

https://www.acwing.com/problem/content/425/

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int N=105;
int a[N];
int f[1005];
int T,n;
int v[N],w[N];
int main(){
    cin>>T>>n;
    for(int i=1;i<=n;i++){
        cin>>v[i]>>w[i];
    }
    for(int i=1;i<=n;i++){
        for(int j=T;j>=v[i];j--){
            f[j]=max(f[j],f[j-v[i]]+w[i]);
        }
    }
    cout<<f[T]<<endl;
  return 0;
}
//  freopen("testdata.in", "r", stdin);

1024. 装箱问题

https://www.acwing.com/problem/content/1026/

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int N=35;
int a[N];
int f[20010];
int T,n;
int v[N],w[N];
int main(){
    cin>>T>>n;
    for(int i=1;i<=n;i++){
        cin>>v[i];
        w[i]=v[i];
    }
    for(int i=1;i<=n;i++){
        for(int j=T;j>=v[i];j--){
            f[j]=max(f[j],f[j-v[i]]+w[i]);
        }
    }
    cout<<T-f[T]<<endl;
  return 0;
}
//  freopen("testdata.in", "r", stdin);

1022. 宠物小精灵之收服

https://www.acwing.com/problem/content/1024/

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
int N,M,K;
int f[1010][510];
int v1[105],v2[105];
int main(){
    cin>>N>>M>>K;
    for(int i=1;i<=K;i++){
        cin>>v1[i]>>v2[i];
        v2[i];
    }
    for(int i=1;i<=K;i++){
        for(int j=N;j>=v1[i];j--){
            for(int k=M-1;k>=v2[i];k--){//由于体力0也不行,这里直接-1处理
                f[j][k]=max(f[j][k],f[j-v1[i]][k-v2[i]]+1);
            }
        }
    }
    int k=M-1;
    //逆向推 看看答案是从那个状态转移过来
    while(k>0 && f[N][k-1]==f[N][M-1])k--;
    cout<<f[N][M-1]<<" "<<M-k<<endl;
  return 0;
}
//  freopen("testdata.in", "r", stdin);

278. 数字组合

https://www.acwing.com/problem/content/280/

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
int a[105];
LL f[10010];

int n,m;
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    f[0]=1;
    for(int i=1;i<=n;i++){
        for(int j=m;j>=a[i];j--){
            f[j]+=f[j-a[i]];
        }
    }
    cout<<f[m]<<endl;
  return 0;
}
//  freopen("testdata.in", "r", stdin);

1023. 买书

https://www.acwing.com/problem/content/1025/

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
int a[4]={10,20,50,100};
LL f[1010];

int n,m;
int main(){
    cin>>m;
    f[0]=1;
    for(int i=0;i<4;i++){
        for(int j=a[i];j<=m;j++){
            f[j]+=f[j-a[i]];
        }
    }
    cout<<f[m]<<endl;
  return 0;
}
//  freopen("testdata.in", "r", stdin);

532. 货币系统

https://www.acwing.com/problem/content/534/

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
int T;
const int N=110;
int a[N];
int f[25010];
int n;
int main(){
    cin>>T;
    while(T--){
        cin>>n;
        memset(f,0,sizeof f);
        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        sort(a,a+n);
        int M=a[n-1];
        f[0]=1;
        int ans=0;
        for(int i=0;i<n;i++){
            if(!f[a[i]]) ans++;
            for(int j=a[i];j<=M;j++){
                f[j]=max(f[j],f[j-a[i]]);
            }
        }
        cout<<ans<<endl;
    }
  return 0;
}
//  freopen("testdata.in", "r", stdin);

1019. 庆功会

https://www.acwing.com/problem/content/description/1021/

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int N=510,M=6010;
int v[N],w[N],s[N];
int f[M];
int n,m;
int main(){
    cin>>n>>m;
    for(int i=0;i<n;i++){
        cin>>v[i]>>w[i]>>s[i];
    }
    for(int i=0;i<n;i++){
        for(int j=m;j>=0;j--){
            for(int k=0;k<=s[i]&&k*v[i]<=j;k++){
                f[j]=max(f[j],f[j-k*v[i]]+k*w[i]);
            }
        }
    }
    cout<<f[m]<<endl;
  return 0;
}
//  freopen("testdata.in", "r", stdin);

7. 混合背包问题

https://www.acwing.com/problem/content/7/

#include <iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
using namespace std;
int N,V;
int dp[1005];
struct Good{
    int s,v,w;
};
vector<Good> goods;
int nv,nw,ns;
int main(){
    cin>>N>>V;
    for(int i=1;i<=N;i++){
        cin>>nv>>nw>>ns;
        if(ns<=0){
                goods.push_back({ns,nv,nw});
        }
        else {
            for(int k=1;k<=ns;k*=2){
                ns-=k;
                goods.push_back({-1,k*nv,k*nw});
            }
            if(ns>0){
                goods.push_back({-1,ns*nv,ns*nw});
            }
        }
    }
    for(auto g:goods){
        if(g.s==-1){
            for(int j=V;j>=g.v;j--){
                dp[j]=max(dp[j],dp[j-g.v]+g.w);
            }
        }
        else {
            for(int j=g.v;j<=V;j++){
                dp[j]=max(dp[j],dp[j-g.v]+g.w);
            }
        }
    }
    cout<<dp[V];
  return 0;
}
//  freopen("testdata.in", "r", stdin);

8. 二维费用的背包问题

https://www.acwing.com/problem/content/8/

#include <iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
using namespace std;
int N,V,M;
int v[1005],m[1005],w[1005];
int dp[1005][1005];//用了j体积,k重量的最大价值
int main(){
    cin>>N>>V>>M;
    for(int i=1;i<=N;i++){
        cin>>v[i]>>m[i]>>w[i];
    }

    for(int i=1;i<=N;i++){
        for(int j=V;j>=v[i];j--){
            for(int k=M;k>=m[i];k--){
                dp[j][k]=max(dp[j][k],dp[j-v[i]][k-m[i]]+w[i]);
            }
        }
    }
    cout<<dp[V][M];
  return 0;
}
//  freopen("testdata.in", "r", stdin);

1020. 潜水员(体积至少是xx的做法)

https://www.acwing.com/problem/content/1022/
状态方程表示与之前体积恰好是xx变成至少是xx即可做此题,同时由于条件变成至少.可以从负数体积状态转移过来,这里所有负数体积都设置为0体积状态(即都不选)

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int N=25,M=85;
int f[N][M];//f(i,j)氧气体积至少为i,氮气体积至少为j的最少方案
int n,m,K;
int main(){
    cin>>n>>m;
    cin>>K;
    memset(f,0x3f,sizeof f);
    f[0][0]=0;
    while(K--){
        int a,b,c;
        cin>>a>>b>>c;
        for(int j=n;j>=0;j--){
            for(int k=m;k>=0;k--){//由于状态方程变成 至少 可以从负数体积转移过来 统一吧负数状态设置成0体积
                f[j][k]=min(f[j][k],f[max(0,j-a)][max(0,k-b)]+c);
            }
        }
    }
    cout<<f[n][m]<<endl;
  return 0;
}
//  freopen("testdata.in", "r", stdin);

1013. 机器分配

https://www.acwing.com/problem/content/1015/

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int N=15,M=20;
int a[N][M];
int n,m;
int f[N][M];
int ways[N];
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>a[i][j];
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=0;j<=m;j++){
            for(int k=0;k<=j;k++){
                f[i][j]=max(f[i][j],f[i-1][j-k]+a[i][k]);
            }
        }
    }
    cout<<f[n][m]<<endl;
    int j=m;
    for(int i=n;i;i--){
        for(int k=0;k<=j;k++){
            if(f[i][j]==f[i-1][j-k]+a[i][k]){
                ways[i]=k;
                j-=k;
                break;
            }
        }
    }
    for(int i=1;i<=n;i++){
        cout<<i<<" "<<ways[i]<<endl;
    }
  return 0;
}
//  freopen("testdata.in", "r", stdin);

11. 背包问题求方案数

https://www.acwing.com/problem/content/11/

#include <iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
using namespace std;
int N,V;
const int mod=1e9+7,INF=1e5;
int v[1005],w[1005],f[1005],dp[1005];
int main(){
    cin>>N>>V;
    for(int i=1;i<=N;i++){
        cin>>v[i]>>w[i];
    }
    for(int i=1;i<=V;i++){
        dp[i]=-INF;
    }
    f[0]=1;
    for(int i=1;i<=N;i++){
        for(int j=V;j>=v[i];j--){
            int temp=max(dp[j],dp[j-v[i]]+w[i]);
            int s=0;
            if(temp==dp[j]){
                s+=f[j];
            }
            if(temp==dp[j-v[i]]+w[i]){
                s+=f[j-v[i]];
            }
            if(s>=mod) s-=mod;
            dp[j]=temp;
            f[j]=s;
        }
    }
    int Maxv=0;
    for(int i=0;i<=V;i++){
        Maxv=max(Maxv,dp[i]);
    }
    int res=0;
    for(int i=0;i<=V;i++){
        if(dp[i]==Maxv){
            res+=f[i];
            if(res>=mod) res-=mod;
        }
    }
    cout<<res<<endl;
  return 0;
}
//  freopen("testdata.in", "r", stdin);

12. 背包问题求具体方案

https://www.acwing.com/problem/content/12/

#include <iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
using namespace std;
int N,V;
const int Maxn=1e3+5;
int w[Maxn],v[Maxn],dp[Maxn][Maxn];
int main(){
    cin>>N>>V;
    for(int i=1;i<=N;i++){
        cin>>v[i]>>w[i];
    }
    for(int i=N;i>=1;i--){
        for(int j=0;j<=V;j++){
            dp[i][j]=dp[i+1][j];
            if(j>=v[i]){
                dp[i][j]=max(dp[i+1][j],dp[i+1][j-v[i]]+w[i]);
            }
        }
    }
    for(int i=1;i<=N;i++){
        if(dp[i][V]==dp[i+1][V-v[i]]+w[i]){
            cout<<i<<" ";
            V-=v[i];
        }
    }
  return 0;
}
//  freopen("testdata.in", "r", stdin);

487. 金明的预算方案

https://www.acwing.com/problem/content/489/

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<unordered_map>
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef pair<int, int>PII;
const int N=65,M=32010;
int n,m;
PII father[N];
vector<PII>child[N];
int f[M];
int main(){
    cin>>m>>n;
    for(int i=1;i<=n;i++){
        int v,p,q;
        cin>>v>>p>>q;
        p*=v;
        if(!q){
            father[i]={v,p};
        }
        else child[q].push_back({v,p});
    }
    for(int i=1;i<=n;i++){
        for(int u=m;u>=0;u--){
            for(int j=0;j<1<<child[i].size();j++){
                int v=father[i].x;//爹必须选
                int w=father[i].y;
                for(int k=0;k<child[i].size();k++){//二进制枚举
                    if(j>>k&1){
                        v+=child[i][k].x;
                        w+=child[i][k].y;
                    }
                }
                if(u>=v) f[u]=max(f[u],f[u-v]+w);
            }
        }
    }
    cout<<f[m]<<endl;
  return 0;
}
//  freopen("testdata.in", "r", stdin);
posted @ 2021-05-24 10:58  一个经常掉线的人  阅读(73)  评论(0)    收藏  举报