E - Arpa's weak amphitheater and Mehrdad's valuable Hoses

本文介绍了一道结合0-1背包问题与并查集算法的编程题解题思路。题目要求在考虑人际友谊关系约束下,选择一组最具有魅力的参与者,使得总魅力值最大且不超过体重限制。文章详细展示了使用动态规划与并查集求解的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

dp 0-1背包+并查集 CodeForce 742D
http://codeforces.com/problemset/problem/742/D
动态规划专题训练
题目大意:选几个美丽的小姐来参加舞会,但是每位小姐都是有着体重和魅力值,要求在有总体重上限w的情况下尽可能的选出总魅力值最高的小姐来参加。
当然如果是这样就可以直接套0-1背包的模板了。然而还加上了一个限制,就是每一位小姐都会和其他的小姐之间有个友谊关系,在有友谊关系的情况下,要么只选一个人,要么全部都请过去。
思路:
先用并查集解决友谊圈的问题,找出同是一个友谊圈的小姐,并放在一块。
接着利用0-1背包的思路,来解决。
状态转移方程 dp(s)=max{dp(s-w(k))+b(k)};//k是在一个圈里的小姐
然后在进行一次判断就是这个跟这个圈的小姐全部都选上的方案相比怎么样
dp(s)=max{dp(s-wl)+bl};

做的时候小心点就好了,今天唯一一次AC

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;

int d[1006];
int v[1006];
int a[1006],b[1006];
vector<int> h[1006];
int al[1006],bl[1006];
int find(int s)
{
    return s==v[s]?s:v[s]=find(v[s]);
}
int n,m,w;

void read()
{
    scanf("%d %d %d",&n,&m,&w);
    for(int i = 0; i <= n; i++ )
        v[i]=i;
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
    }
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &b[i]);
    }
    for(int i = 0; i < m; i++)
    {
        int u,vi;
        scanf("%d %d",&u, &vi);
        int x = find(u);
        int y = find(vi);
        v[x]=y;
    }
}
int main()
{
    memset(d, 0, sizeof(d));
    memset(al, 0 ,sizeof(al));
    memset(bl, 0, sizeof(bl));
    read();
    for(int i = 1; i <= n; i++)
    {
        h[find(i)].push_back(i);
        al[find(i)] += a[i];
        bl[find(i)] += b[i];
    }

    for(int i = 1; i <= n; i++)
    {
        if(h[i].empty()) continue;
        for(int j = w; j >= 0; j--)
        {
            for(int k = 0; k < h[i].size(); k++)
            {
                if(j - a[h[i][k]] >= 0)
                    d[j]=max(d[j - a[h[i][k]]] +b[h[i][k]],d[j]);
            }
            if(j - al[i] >= 0) d[j]=max(d[j - al[i]]+bl[i], d[j]);
        }
    }
    int ans=-1;
    for(int i = 0; i <= w; i++ ) ans=max(ans, d[i]);
    printf("%d\n",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值