寒假c语言练习题

P1455 搭配购买

P1455 搭配购买 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

一个背包和并查集结合的题目,把需要一起购买的东西绑在一起,后面用01背包求出最大的价值。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int fa[100005],p[10010],v[10010],f[10010];
void unionn(int a,int b);
int find(int i);
int main()
{
    int n,m,w,i,j;
    cin>>n>>m>>w;
    for(i=1;i<=n;i++){
        fa[i]=i;//初始化
        cin>>p[i]>>v[i];
    }
    for(i=1;i<=m;i++){
        int x,y;
        cin>>x>>y;
        unionn(x,y);//合并需要一起购买的
    }
    for(i=1;i<=n;i++){//01背包
        if(find(fa[i]==i))//判断是不是根节点,价格累加在这里
        for(j=w;j>=p[i];j--){
            f[j]=max(f[j],f[j-p[i]]+v[i]);
        }
    }
    cout<<f[w];
}
void unionn(int a1,int b1)
{
    int i,j;
    i=find(a1);
    j=find(b1);
    if(i!=j){
        p[j]+=p[i];
        v[j]+=v[i];
        fa[i]=j;
    }
}
int find(int i)
{
    if(fa[i]==i)
    {
        return i;
    }
    else{
        fa[i]=find(fa[i]);
        return fa[i];
    }
}

P2080 增进感情

P2080 增进感情 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

每个活动都可以选择做或者不做(好像和背包一样)从第一个活动搜索到最后一个枚举所有组合,可以考虑的一个剪枝是已经最幸福的时候就不用继续了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[50][2];
int ans=0x3f3f3f3f,xm=0,xh=0,v,n;
void dfs(int num);
int main()
{
    int i;
    cin>>n>>v;
    for(i=1;i<=n;i++)
    {
        cin>>a[i][0]>>a[i][1];
    }
    dfs(1);//参数表示第几个活动
    if(ans==0x3f3f3f3f)cout<<-1;//不能在一起就释怀 输出-1
    else cout<<ans;
}
void dfs(int num)
{
    if(num<=n){
        for(int i=0;i<=1;i++)//两种选择做或者不做
        {
            if(i){
                xm+=a[num][0];
                xh+=a[num][1];
            }
            if(xm+xh>v){
                ans=min(ans,abs(xm-xh));//更新答案
                if(ans==0)return;//如果已经是幸福生活就不用继续了
            }    
            dfs(num+1);//下一个活动
            if(i){//回溯,只需要恢复做过的
                xm-=a[num][0];
                xh-=a[num][1];
            }
        }
    }
    else return;
}

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值