首页 > 代码库 > Codeforces Round #385(div 2)

Codeforces Round #385(div 2)

A

=w=

B

QwQ

C

题意:n个点m条边的无向图,其中有k个特殊点,你在这张图上尽可能多的连边,要求k个特殊点两两不连通,问最多能连多少边

分析:并查集

  对原图做一次并查集,找出特殊点所在集合中节点数量最大的那个,将剩余没有特殊点的集合并到那个集合中去。

  计算答案时候先根据集合的点数算出最大边数,再减去初始边数就是最多加的边数

D

题意:好像是个交互题,题目太长,不想看

分析:留坑

E

题意:Hongcow想去一家店买一些卡片,于是他和店主完了个游戏。每个回合,Hongcow选择做下面两件事中的一件事:1.收集一张红色令牌和一张蓝色令牌。2.购买一张卡片。对于第i张卡片,用三个参数描述,colori,ri,bi,代表第i张卡片的颜色,购买它需要的红色/蓝色令牌数。此外,如果当前Hongcow已经买了A张红色卡片和B张蓝色卡片,那么购买第i张卡片的费用分别为max(0,ri - A)以及max(0,bi - B),注意卡片和令牌的区别,卡片购买后就一直属于Hongcow了。

分析:状压DP

  先买r和b,再买card肯定不会影响结果

  可以将r和b分开考虑:f[s][i]表示状态s(表示各个card是否买了),省了i个r,最少花费多少个b

  转移的时候要先预处理出每个s对应的sumr[s]和sumb[s]表示R和B在当前状态中出现了多少个

  注意到r的节省是等差数列求和,所以最多是n*(n-1)/2,总的复杂度是O(n^3*2^n)

  贴一份转移时候的代码:

技术分享
 1     for(int i=0;i<=n*(n-1)/2;++i) 2         for(int s=0;s<MAX;++s) 3             for(int j=0;j<n;++j) 4                 if(((1<<j)&s)!=0) 5                 { 6                    if(sumr[s-((1<<j)&s)]>=r[j+1]) 7                    { 8                        if(i>=r[j+1]) 9                        f[s][i]=min(f[s][i],f[s-((1<<j)&s)][i-r[j+1]]+max(0,b[j+1]-sumb[s-((1<<j)&s)]));10                    }11                    else12                    {13                     if(i>=sumr[s-((1<<j)&s)])14                         f[s][i]=min(f[s][i],f[s-((1<<j)&s)][i-sumr[s-((1<<j)&s)]]+max(0,b[j+1]-sumb[s-((1<<j)&s)]));15                    }16                 }
View Code

 

Codeforces Round #385(div 2)