USACO Barn Repair

本文介绍了一个基于贪心策略解决Barn1问题的方法。该算法首先使用一块板子覆盖所有区域,接着按间隔区域大小进行排序,并逐一删除最大的间隔直至被分割成所需数量的段或所有间隔被删完。特别考虑了开始和结束区域的特殊情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  想不出怎么贪心,后来网上查了下,先用一整块板子覆盖全部,然后把间隔区域排序,从大逐一删除,知道被分割成cow数量段或者全部间隔区域删除完全。
注意开始和结束区域可能不占1次划分
/*

ID: hubiao cave

PROG: barn1

LANG: C++

*/




#include<iostream>

#include<fstream>

#include<string>


using namespace std;

struct dist
{
	int start;
	int end;
	int range;
};
char buf[202];
dist distarray[202];
int buf1[202];
void InsertSort(int number);
void InsertSort2(int number);


int main()

{




    ifstream fin("barn1.in");

    ofstream fout("barn1.out");

	int barn,stall,cow;
	fin>>barn>>stall>>cow;
	int bestall;
	for(int i=1;i<=cow;i++)
		fin>>buf1[i];
	InsertSort2(cow);

	if(cow==1)
		{
		fout<<1<<endl;
		return 0;
		}
	int j=0;
	for(int i=1;i<=cow;i++)
	{
		int temp;
		//fin>>temp;
		temp=buf1[i];

		if(i==1)
		{
			bestall=temp;
			if(temp!=1)
			{
				j++;
				distarray[j].end=temp;
				distarray[j].range=temp-1;
				continue;
			}
		}
		if(i==cow)
		{
			if(temp!=stall)
			{
				j++;
				distarray[j].start=temp;
				distarray[j].range=stall-temp;
				//break;
			}

		}
		if(temp>bestall+1)
		{
			j++;
			distarray[j].start=bestall;
			distarray[j].end=temp;
			distarray[j].range=temp-bestall-1;
			bestall=temp;
		}
		else
		{
			bestall=temp;

		}


	}


	InsertSort(j);
	for(int i=j;i>=1;i--)
	{
		if(distarray[i].start==0||distarray[i].end==0)
		{
			stall-=distarray[i].range;
		}
	}

	for(int i=j;i>=1;i--)
	{
		if(barn>1)
		{
			if(distarray[i].start!=0&&distarray[i].end!=0)
			{
				stall-=distarray[i].range;
				barn--;
			}

			//stall-=distarray[i].range;
		}
	}
	fout<<stall<<endl;


	

    return 0;


}


void InsertSort(int number)
{
	int i=2;
	for(;i<=number;i++)
	{
		distarray[0]=distarray[i];
		int j=i-1;
		for(;j>0;j--)
		{
			if(distarray[j].range>distarray[0].range)
			{
				distarray[j+1]=distarray[j];
			}
			else
				break;

		}
		distarray[j+1]=distarray[0];

	}
}


void InsertSort2(int number)
{
	int i=2;
	for(;i<=number;i++)
	{
		buf1[0]=buf1[i];
		int j=i-1;
		for(;j>0;j--)
		{
			if(buf1[j]>buf1[0])
			{
				buf1[j+1]=buf1[j];
			}
			else
				break;

		}
		buf1[j+1]=buf1[0];

	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值