CCF:202303-2 垦田计划--C++

最少开垦时间设为i,他的范围应该是k(开垦一块区域的最少时间)到nowMost(不用任何资源的最短开垦时间)

思路:对所有开垦时间大于i的土地使用资源,使之开垦时间为i,如果资源m够所有的土地开垦时间等于或小于i,则i就是最短开垦时间

七十分:

#include<iostream>

/*
#include<cmath> 
#include<cstring>
#include<string>
#include<string.h>
#include<stdio.h>
#include<algorithm>*/

using namespace std;

int main()
{
	int n;//n块地
	int m;//m的资源
	int k;//最少可能天数 
	
	int t[101];//开垦需要天数
	int c[101];//减少一天需要资源 
	
	cin>>n>>m>>k; 
	
	int nowMost=0;//记录不用资源而开发所需的最长时间 
	
	for(int i=0;i<n;i++)
	{
		cin>>t[i];
		cin>>c[i];
		if(t[i]>nowMost) nowMost=t[i]; 
	}
	
	
	int Least=nowMost;//最少天数从k一直加加直到资源可以满足
	int nowR=m;//目前剩下的资源
	int flag=1;//代表资源足够 
	for(int i=k;i<nowMost;i++)//第一个满足条件的i即是最短开垦时间 
	{
		flag=1;// 
		nowR=m;
		for(int j=0;j<n;j++)//对每一块地分配资源使之完成时间均为i,看看资源能否满足,能则i是最少开垦时间
		{
			if(t[j]>i)//只有本来的开垦时间比较大的才需要资源来减少时间 
			{
			nowR -=c[j]*(t[j]-i);
			if(nowR<0)
			{
			   flag=0;//资源不够,最少开垦时间不能为i 
			   break;	
			}
			 } 
			 
		 }
		 
		 if(flag==1&&Least>i) //
		 {
		 	Least=i;
		 	break;///可以得到最短时间 
		  } 
	 }
	 
	 
	 cout<<Least; 
  
  
 
    return 0; 
}

优化:使用二分法,根据中间点能否满足条件动态的设置判断的数据范围

#include<iostream>
#include <bits/stdc++.h> 
 
using namespace std;
 
 
 int t[100001];//开垦需要天数
 int c[100001];//减少一天需要资源 
 
 
 
 bool FindMin(int s,int e,int t[],int c[],int m,int n1)//s--e代表可能的完成时间 
 {
 	int flag=1;
 	int nowR=m;
 	int n=n1;
 	
 	for(int j=n-1;j>=0;j--)
		{
			if(t[j]>(s+e)/2)//判断中间的时间能不能满足条件 
			{
			nowR -=c[j]*(t[j]-(e+s)/2);
			if(nowR<0)
			{
			   flag=0;//资源不够,最少开垦时间不能为i 
			   return false;
			}
			 } 
			 
		 }
		  
		 return true; 
		 
		 
  } 
 
 
int main()
{
	int n;//n块地
	int m;//m的资源
	int k;//最少可能天数 
	
	
	
	cin>>n>>m>>k; 
	
	int nowMost=0;//记录不用资源而开发所需的最长时间 
	
	for(int i=0;i<n;i++)
	{
		cin>>t[i];
		cin>>c[i];
		if(t[i]>nowMost) nowMost=t[i]; 
	}
	

	int l=k;
	int r=nowMost;
	while(l<=r)//根据中间时间是否能满足条件动态的设置判断范围最终找到一个最小时间 
	{
		if(FindMin(l,r,t,c,m,n))//时间可以小一点 
		r=((r+l)/2)-1;
		else l=((r+l)/2)+1; //时间要大一点 
	}
	
	
	cout<<l;

    return 0; 
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值