2020暑期牛客多校训练营第九场(F)Groundhog Looking Dowdy(贪心)

Groundhog Looking Dowdy

原题请看这里

题目描述:

n n n天,每天穿一件衣服,第 i i i 天有 k i k_i ki 件衣服可以穿,穿第 j j j 件衣服的的权值为 a i j a_{i j} aij 。从 n n n 天中选择 m m m 天,求这 m m m 天中,所穿衣服的权值最大与最小值的最小差是多少。

输入描述:

第一行包含两个整数 n {n} n m {m} m
然后 n {n} n行,每行包含一个整数 k i k_i ki,代表第 i t h {i ^ {th}} ith天可以穿的衣服的数量。然后 k i k_i ki个整数 a i j a_ {ij} aij

输出描述:

一行打印最小差异。

样例输入:

4 3
1 3
2 8 6
1 2
3 1 7 5

样例输出:

2

思路:

首先,我们想到二维数组肯定是不可能的,所以我们只能开一维的数组。
所以我们就可以开个结构体在输入的同时记录一下是第几天穿的和权值是多少,再对数组按权值大小从小到大排序,然后用移动窗口来维护一下答案即可。

A C AC AC C o d e Code Code:

#include
#define ll long long
using namespace std;
const int MAXN=2e6+6;
struct node{int id,sum;}a[MAXN];
bool cmp(node x,node y){return x.sum<y.sum;}
int n,m,k,len,v[MAXN];
int ans=1e9;
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i){
		scanf("%d",&k);
		for(int j=1;j<=k;++j){
			scanf("%d",&a[++len].sum);
			a[len].id=i;
		}
	}
	sort(a+1,a+len+1,cmp);
	int l=1,r=0,tmp=0;
	while(tmp<m){
		r++;
		if(!v[a[r].id]){
			v[a[r].id]++;
			tmp++;
		}
	}//找到第一个符合条件的
	for(l,r;r<=len;){
		ans=min(ans,a[r].sum-a[l].sum);
		v[a[l].id]--;
		tmp--;
		l++;
		if(!v[a[l].id]) v[a[l].id]++,tmp++;
		while(tmp<m&&r<=len){
			r++;
			if(!v[a[r].id]){
				v[a[r].id]++;
				tmp++;
			}
		}
	}printf("%d\n",ans);
}

你可能感兴趣的:(贪心算法)