首页 > 其他 > 详细

2019浙工大迎新赛

时间:2020-12-17 15:45:16      阅读:28      评论:0      收藏:0      [点我收藏+]

2019浙工大迎新赛

Yukikaze的复仇

题意:技术分享图片

题解:

\[\begin{align*} &设\Delta=x-y,sum=糖果和,a为Yurikaze吃的糖果,b为Suzukaze吃的糖果\&题意变为求 ans=\Delta+a-b>0且最小\&开始喜闻乐见地推公式,ans=\Delta+sum-2*b>0且最小,即求一个最大的2*b<\Delta+sum,可以把所有的糖果都乘以2,然后01背包,价值和重量都是糖果对应的智商值\&至于黏在一起的糖果DSU处理 \end{align*} \]

#include<bits/stdc++.h>
#include<time.h>
using namespace std;
const int maxn=2e6+5;
namespace DSU
{
    int  father[maxn],rank[maxn],candy[maxn];
    void init(int n){for(int i=1;i<=n;i++) {father[i]=i;rank[i]=1;}}
    int find(int x){return x==father[x]?x:father[x]=find(father[x]);}
    void unionSet(int x,int y)
    {
        int xx=find(x),yy=find(y);
        if(xx==yy) return;
        if(rank[xx]>rank[yy]) swap(xx,yy);
        father[xx]=yy;rank[yy]+=rank[xx];
        candy[yy]+=candy[xx];
    }
}
using namespace DSU;
int dp[maxn];
int main()
{
    int n,m,x,y,l,r,sum=0;
    scanf("%d%d%d%d",&n,&m,&x,&y);init(n);
    for(int i=1;i<=n;i++){
        scanf("%d",&candy[i]);sum+=candy[i];
    }
    while(m--){
        scanf("%d%d",&l,&r);
        unionSet(l,r);
    }
    vector<int>vc;
    for(int i=1;i<=n;i++){
        if(i==father[i]) vc.push_back(2*candy[i]);
    }
    sum+=x-y;
    if(sum<=0) {printf("-1");return 0;} 
    for(int i=0;i<vc.size();i++){
        for(int j=maxn-1;j>=vc[i];j--){
            dp[j]=max(dp[j],dp[j-vc[i]]+vc[i]);
        }
    }
    printf("%d",sum-dp[sum-1]);
}


2019浙工大迎新赛

原文:https://www.cnblogs.com/zx0710/p/14148991.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!