Codeforces Round #585 (Div. 2)

当时4/6

补题5/6

意识流6/6


A题:没什么好说的。

B题:一下看错了题意。还以为是统计区间和的正负方案数,结果是乘积。

C题:样例对思路有着很大的启发作用。数一下ab与ba的方案数,把它们简单分个组就好了。。

D题:贪心的思路大致是,从破坏平衡者的角度出发,他可以选择尽量使前一半大(小)于后一半,难得讨论的这么清楚。。。

E题:需要把相同数字都聚拢到一段一段,数字集合只有20,复杂度和做法十分显然,但我还是打假了。考虑DP[i][j]表示要把所有颜色i放到j的前面所需要的ij之间的操作代价。然后状压表示当前已经放完了sta的状态,要把某一颜色放至末尾的操作代价。我也不知道代码怎么会写成这样。。。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const long long inf = 1ll*400000*1ll*400000;
ll d[2002020];
ll cnt[50][50];
vector<int>col[30];
int n;
int main(){
	cin >> n;
	for (int i = 0; i < n ; i++){
		int x; cin>>x;
		x--;
		col[x].push_back(i);
	}
	for(int i=0;i<20;i++){
		for(int j=0;j<20;j++)if(i!=j && (int)col[i].size()>0 && (int)col[j].size()>0){
 
			int pos2=0;
			for(int pos1=0;pos1<(int)col[i].size();pos1++){
				while(true){
					if(pos2==(int)col[j].size()-1 || col[j][pos2+1]>col[i][pos1])break;
					pos2++;
				}
				if(col[i][pos1]>col[j][pos2])cnt[i][j]+=pos2+1;
			}
		}
	}
	for(int mask=0;mask<(1<<20);mask++)d[mask]=inf;
	d[0]=0;
	for(int mask=0 ;mask<(1<<20);mask++){
		vector<int>v;
		for(int i=0;i<20;i++)if(mask&(1<<i))v.push_back(i);
 
		for(int i=0;i<20;i++)if((mask&(1<<i))==0){
			long long sum=0;
			for(int j=0;j<(int)v.size();j++)sum+=cnt[v[j]][i];
 
			d[mask|(1<<i)]=min(d[mask|(1<<i)],d[mask]+sum);
		}
	}
	cout << d[(1<<20)-1]<<endl;
	return 0;
}

F题:我觉得我会(大部分)啊。要从p个点中选出若干个点,使得它们之间,两两矛盾的点对必须不能同时存在,两两complaints的点对至少存在一个。同时要选取一个[1,M]之间的频率,使得该频率满足所有被选的节点的区间[Li,Ri]。这样的话对于节点之间的关系,就是朴素2-sat,然后频率范围也才40w,不如对它开一个f必须大于等于i的节点,用所有区间对它进行约束。当然要保证f与f+1的TRUE点之间也是有连边的。

STD CODE:

http://codeforces.com/blog/entry/69815

 

主要是晚上又可以打div2了,上周div2再不写就。。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值