D - Data Center-2014-2015 ACM-ICPC, NEERC, Southern Subregional Contest

贪心

先把高低电压各存在一个数组并排序

题目思路很简单。  就是先 贪心得到 最少的机器数num

然后分2种情况

1:num<= 所有低电压机器数量  此时 先假设全部低电压被选了

然后  根据 if  (当前cap之和是否>= m)  来贪心  ( 不断比较"已选"的最小cap的低电压机器 和大cap的高电压机器)  (都已排序)

2: num>总低电压机器数量(a)

此时 先假设全部低电压机器被选了,并且再选num-a步 较大cap的高电压(已排序)

 然后也是  根据 if  (当前cap之和是否>= m)  来贪心  ( 不断比较"已选"的最小cap的低电压机器 和”未选“的较大cap的高电压机器) (都已排序)



代码写得比较长。。。乱


#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue> 
#include <set>
#include <vector>
using namespace std;
struct ren
{
	__int64 ca;
	int v;
	__int64 code; 
};

ren tm[100000*2+5];				//所有机器 //升序
ren nm1[100000*2+5];		//保存低电压code  升序
ren nm2[100000*2+5];		//保存高电压code  升序
__int64 ans[100000*2+5];    //记录选过了的code
__int64 vis[100000*2+5];   //标记要删除的code
int cmp(ren a,ren b)
{
	if (a.ca!=b.ca)
		return a.ca>b.ca; 
	else
	{
		return a.v>b.v;
	}
}
int main()
{
	
	__int64 i,j;
	__int64 n,m,cop_m;
	scanf("%I64d %I64d",&n,&m);
	cop_m=m;
	for (i=1;i<=n;i++)
	{
		scanf("%I64d %d",&tm[i].ca,&tm[i].v); 
		tm[i].code=i;
	}
	
	sort(tm+1,tm+1+n,cmp); 
	__int64 ok1=0;
	__int64 ok3=0;	
	__int64 ok2=0;
	__int64	star=0;
	for (i=1;i<=n;i++)
	{
		if (tm[i].v==1)
		{
			nm1[++ok1].ca=tm[i].ca;
			nm1[ok1].code=tm[i].code;
			
		}
		else
		{ 
			nm2[++ok2].ca=tm[i].ca;
			nm2[ok2].code=tm[i].code;
			
		}
	} 
	__int64 num=0;  
	for (i=1;i<=n;i++)
	{
		
		if (m<=0) break; 
		m-=tm[i].ca;
		num++;  
	} 
	m=cop_m;
	__int64 max_low=0;          //最小低电压机器数
	if (num<=ok1)			// 最小机器数小于等于 低电压机器数
	{
		
		for(i=1;i<=num;i++)
		{
			star+=nm1[i].ca;
			ans[++ok3]=nm1[i].code;
			
		}
		
		
		max_low=num;   //此情况下 假设先全部选低电压  
		__int64 it;
		for ( i=num,j=1;j<=ok2 &&i>=1;)
			
		{
			if (star>=m) break;
			star=star-nm1[i].ca+nm2[j].ca;
			//	sort(ans+1,ans+1+ok3);
			//	it= lower_bound(ans+1,ans+1+ok3,nm1[i].code)-&ans[1]+1;
			//	ans[it]=0;
			vis[nm1[i].code]=-1;   //删除该编号
			ans[++ok3]=nm2[j].code;
			max_low--;
			i--;
			j++;  
		}
		
		
		
		
	}
	else						// 最小机器数大于 低电压机器数
	{
		 
		for(i=1;i<=ok1;i++)    //此情况下 假设先全部选低电压 再从最大cap值的高电压机器凑够num个
		{
			star+=nm1[i].ca;
			ans[++ok3]=nm1[i].code;
			
		}
		
		for(i=1;i<=num-ok1;i++)
		{
			star+=nm2[i].ca;
			ans[++ok3]=nm2[i].code;
			
		}
		
		
		max_low=ok1;          //最小低电压机器数为ok1个(全部低电压机器)
		__int64 it;
		for ( i=ok1,j=num-ok1+1;j<=ok2 &&i>=1;)
			
		{
			if (star>=m) break;
			
			star=star-nm1[i].ca+nm2[j].ca;
			//	sort(ans+1,ans+1+ok3);
			//	it= lower_bound(ans+1,ans+1+ok3,nm1[i].code)-&ans[1]+1;
			//	ans[it]=0;
			vis[nm1[i].code]=-1;         //删除该编号
			ans[++ok3]=nm2[j].code;
			max_low--;
			i--;
			j++;  
			
		}
		
		
	} 
	int line=0;
	printf("%I64d %I64d\n",num,max_low);
	for (i=1;i<=ok3;i++)
	{
		
		if (	vis[ans[i]] !=-1 )
		{
			if (line!=0) printf(" ");
			printf("%I64d",ans[i]);
			line=1;
		}
		
	}
	
	printf("\n");
	return 0; 
	
} 




你可能感兴趣的:(D - Data Center-2014-2015 ACM-ICPC, NEERC, Southern Subregional Contest)