1. 程式人生 > >P1056 排座椅(找最優解,可以聯想一下貪心)

P1056 排座椅(找最優解,可以聯想一下貪心)

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; }