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)
贴一份转移时候的代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 else 12 { 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 }