P1056 排座椅(找最优解,可以联想一下贪心)

版权声明:转载请在原文附上源连接以及作者,谢谢~ https://blog.csdn.net/weixin_39778570/article/details/83752308

ACM题集:https://blog.csdn.net/weixin_39778570/article/details/83187443
题目:https://www.luogu.org/problemnew/show/P1056
解法:
输入数据保证最优方案的唯一性。所以一定有一个唯一解啦。。。 好像是使用贪心的敏感词 (题还是做得太少了)
单独看行一条通道能隔开越多的人越划算,
单独看列一条通道能隔开越多的人越划算,
但是合起来可以吗?仔细一想,如果一行上有两个相邻的同学说话,只要把列隔开,行怎么隔都不能影响到列,同理列怎么隔也都不能影响到行。所以行列是无印象的,可分开计算没隔开一行或者一列所产生的贡献(隔开人数),贪心按贡献从大到小把矩形分割开来。
如果解不确定就不行,划分有多种。但是题目说了解确定啊。。。
预处理一下每一行和每一列交头接耳的的同学的数量(同行,相邻列,隔开的时候取小的,所以取小的列,行同理)

#include<bits/stdc++.h>
#define ll long long
#define fo(i,j,n) for(register int i=j; i<=n; ++i)
using namespace std;
struct node{
	int val,idx;
	bool operator < (const node &b)const{return val>b.val;}
}H[1005],L[1005];
int m,n,k,l,d;
vector<int> ver;
int main(){
	cin>>m>>n>>k>>l>>d;
	int x1,x2,y1,y2;
	fo(i,1,1005)L[i].idx=H[i].idx=i;
	fo(i,1,d){
		cin>>x1>>y1>>x2>>y2;
		if(x1==x2){ // 同行 
			L[min(y1,y2)].val++;
		}else{     // 同列 
			H[min(x1,x2)].val++;
		}
	}
	sort(H+1,H+1+n);
	fo(i,1,k)ver.push_back(H[i].idx);
	sort(ver.begin(),ver.end());
	fo(i,0,k-1)printf("%d%c",ver[i],i==k-1?'\n':' ');
	
	ver.clear();
	sort(L+1,L+1+m);
	fo(i,1,l)ver.push_back(L[i].idx);
	sort(ver.begin(),ver.end());
	fo(i,0,l-1)printf("%d%c",ver[i],i==l-1?'\n':' ');
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_39778570/article/details/83752308