dp背包练习

背包问题

特点:码量较少(目前只有一题超过1KB)且难度较低(实际难度橙黄绿左右),让新手也可以享受切题的快乐。

 

 没学过背包问题的可以去看看洛谷日报中的背包问题或者背包九讲

1.精卫填海

题目链接

01背包

把物品体积当作价值,体力当做花费

最后遍历一遍dp找到体积满足要求的花费体力最小值

复制代码
#include <iostream>
#include <cstring>
using namespace std;
int m,n,c;
int v[10010],w[10010];
int dp[10010];
int main()
{
    cin>>m>>n>>c;
    for(int i=1;i<=n;i++)
        cin>>v[i]>>w[i];
    for(int i=1;i<=n;i++)
        for(int j=c;j>=w[i];j--)
            dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
    for(int i=1;i<=c;i++)
        if(dp[i]>=m){
            cout<<c-i;
            return 0;
        }
        
    cout<<"Impossible";
    return 0;
}
精卫填海
复制代码

 

2.[USACO09OCT]Bessie's Weight Problem G

题目链接

01背包变形,类似于装箱问题

考虑到本题每个物体的价值就是体积

所以只要把模板中的价格改为体积即可

复制代码
#include <iostream>
using namespace std;
int m,n,v[11000],ans,dp[11000];
int main()
{
    cin>>m>>n;
    for(int i=1;i<=n;i++)
        cin>>v[i];
    for(int i=1;i<=n;i++)
        for(int j=m;j>=v[i];j--)
            dp[j]=max(dp[j],dp[j-v[i]]+v[i]);
    cout<<dp[m];    
    return 0;
}
体积问题
复制代码

 

3.最大约数和

题目链接

01背包变形

先预处理出a放入每个数字的因数和

再用a数组进行背包,每个数字花费为1,价值为a[i]

复制代码
#include <iostream>
using namespace std;
int a[1010],n,dp[1010];
void init()
{
    for(int i=1;i<=1000;i++)
        for(int j=1;j<=i/2;j++)
            if(i%j==0)
                a[i]+=j;
}
int main()
{
    cin>>n;
    init();
    for(int i=1;i<=n;i++)
        for(int j=n;j>=i;j--)
            dp[j]=max(dp[j],dp[j-i]+a[i]);
    cout<<dp[n];
    return 0;
}
最大约数和
复制代码

 

 

4.小书童——刷题大军

题目链接

01背包变形

对于写作业使用01背包,时间为花费,分数为价值,找出能及格的花费时间最小值

刷题时间用贪心,优先选择时间少的题目

复制代码
#include <iostream>
#include <algorithm>
using namespace std;
int n,m,r,k;
int a[110],v[110],w[110],st,ans;
int dp[110],dp2[110];
int main()
{
    cin>>n>>m>>k>>r;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=1;i<=m;i++)
        cin>>w[i];
    for(int i=1;i<=n;i++)
        cin>>v[i];
    for(int i=1;i<=m;i++)
        for(int j=r;j>=w[i];j--)
            dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
    for(int i=1;i<=r;i++)
        if(dp[i]>=k){
            st=r-i;
            break;
        }
    sort(a+1,a+1+n);
    for(int i=1;i<=n;i++){
        st-=a[i];
        if(st<0) break;
        ans++;
    }
    cout<<ans;
    return 0;
}
小书童——刷题大军
复制代码

 

 

5.[USACO2.2]集合 Subset Sums

题目链接

01背包变形

如果n为奇数,则输出0

否则用01背包,

 

复制代码
#include <iostream>
using namespace std;
long long n,dp[2500],sum;
int main()
{
    cin>>n;
    dp[0]=1;
    sum=n*(n+1)/2;
    if(sum%2==1){
        cout<<"0";
        return 0;
    }
    for(int i=1;i<=n;i++)
        for(int j=sum;j>=i;j--)
            dp[j]=dp[j]+dp[j-i];
    cout<<dp[sum/2]/2;
    return 0;
}
集合
复制代码

 

 

 

 

6.yyy2015c01 的 U 盘

题目链接

二分+01背包

先二分出接口大小

再算此时最大价值是否满足条件

复制代码
#include <iostream>
#include <cstring>
using namespace std;
int n,p,s,w[1010],v[1010],dp[1010],ans;
bool check(int x)
{
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=n;i++)
        for(int j=s;j>=w[i];j--)
            if(w[i]<=x)
                dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
    return dp[s]>=p;
}
int main()
{
    int l=1,r=1,mid;
    cin>>n>>p>>s;
    for(int i=1;i<=n;i++){
        cin>>w[i]>>v[i];
        r=max(r,w[i]);
    }
    while(l<=r){
        mid=l+r>>1;
        if(check(mid)){
            ans=mid;
            r=mid-1;
        }
        else
            l=mid+1;
    }
    if(ans==0)
        cout<<"No Solution!";
    else
        cout<<ans;
    return 0;
}
yyy2015c01 的 U 盘
复制代码

 

 

7.Shaass and Bookshelf

 题目链接

01背包变形

 

 

[UwSACO09sOCT]Bes

二分sie's Weight Problem G

posted @   jimhfz  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· Apache Tomcat RCE漏洞复现(CVE-2025-24813)
点击右上角即可分享
微信分享提示