二、笨笨的西瓜种植(watermelon.cpp)
【题目描述】
笨笨种了一块西瓜地,但这块西瓜地的种植范围是一条直线的…… 笨笨在一番研究过后,得出了m个结论,这m个结论可以使他收获的西瓜最多。 笨笨的结论是这样的: 从西瓜地B处到E处至少要种植T个西瓜,这个范围的收获就可以最大化。 笨笨不想那么辛苦,所以他想种植的西瓜尽量少,而又满足每一个所得的结论。
【输入】
第一行两个数n,m(0<n<=5000,0<=m<=3000),表示笨笨的西瓜地长n,笨笨得出m个结论。
接下来m行表示笨笨的m个结论,每行三个数b,e,t(1<=b<=e<=n,0<=t<=e-b+1)
【输出】
输出笨笨最少需种植多少西瓜。
【输入样例】
9 4
1 4 2
4 6 2
8 9 2
3 5 2
【输出样例】
5
------------------------------------------------------------------------------------------------------
此题和NOIP的整数区间十分像,只不过加了一个“长度”和“个数”,怎么处理呢?
它增加了一个长度n之后,我原来以为n没有任何卵用,但是,确实没有什么卵用!
所以,我们只需要处理“个数”就行了:
处理个数嘛,就简单了,加个v数组存次数(个数),每次查一下,查到了就--,在进入循环时判断一下(v!=0)就行了。
就是整数区间的方法了:
按照“右端点”(输入中的e)进行排序,注意:
当“右端点”一样时,一定要判断“左端点”(b)
。
然后,就是j从“右端点”开始,每次符合条件就进入,sum++,查后面的“区间”中有没有此数,有,v就--。
好像没说清楚……大家看代码吧:
#include<cstdio>
#include<algorithm>
using namespace std;
struct k
{
int b;
int e;
int v;
}wl[3002];//定义结构体更方便
int n,m;
int v[5002];//这里的“v”和结构体里的“v”不同,是用来看第i块地有没有种西瓜,种了肯定就不能再种
int cmp(k x,k y)
{
if(x.e!=y.e)
return x.e<y.e;
else
return x.b<y.b;
}
int main()
{
freopen("watermelon.in","r",stdin);
freopen("watermelon.out","w",stdout);//文件输入输出
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
scanf("%d%d%d",&wl[i].b,&wl[i].e,&wl[i].v);
sort(wl,wl+m,cmp);//本来我习惯自己“sort”,结果没“sort”出来
int sum=0;
for(int i=0;i<m;i++)
for(int j=wl[i].e;j>=wl[i].b;j--)
if(v[j]==0&&wl[i].v>0)//判断
{
sum++;
v[j]=1;
for(int k=i;k<m;k++)
if(j<=wl[k].e&&j>=wl[k].b)//我之前傻到还加了一个for循环让p从b到e来比较……
wl[k].v--;
}
printf("%d",sum);
return 0;
}