背景 Background
笨笨:小西瓜,小西瓜~
路人甲:不会呀,这西瓜明明就大着啊……
笨笨:那……大西瓜,大西瓜~
路人甲:这么快就改口了……
笨笨:西瓜西瓜~可爱的西瓜~
描述 Description
笨笨种了一块西瓜地,但这块西瓜地的种植范围是一条直线的……
笨笨在一番研究过后,得出了m个结论,这m个结论可以使他收获的西瓜最多。
笨笨的结论是这样的:
从西瓜地B处到E处至少要种植T个西瓜,这个范围的收获就可以最大化。
笨笨不想那么辛苦,所以他想种植的西瓜尽量少,而又满足每一个所得的结论。
输入格式 Input Format
第一行两个数n,m(0<n<=5000,0<=m<=3000),表示笨笨的西瓜地长n,笨笨得出m个结论。
接下来m行表示笨笨的m个结论,每行三个数b,e,t(1<=b<=e<=n,0<=t<=e-b+1)。
输出格式 Output Format
输出笨笨最少需种植多少西瓜。
分析:
qsort+树状数组。
【参考程序】:
#include<cstring>
#include<cstdio>
#include<iostream>
using namespace std;
struct node
{
int b,e,t;
} a[3010];
int f[5010],c[5010];
int n,m;
int cmp(const void *s,const void *t)
{
node i=*(node *)s,j=*(node *)t;
return i.e-j.e;
}
int lowbit(int x)
{
return x^(x&(x-1));
}
void modify(int x)
{
while (x<=n)
{
c[x]++;
x+=lowbit(x);
}
}
int getsum(int x)
{
int sum=0;
while (x)
{
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)
scanf("%d%d%d",&a[i].b,&a[i].e,&a[i].t);
qsort(a+1,m,sizeof(node),cmp);
memset(c,0,sizeof(c));
memset(f,0,sizeof(f));
int need,ans=0;
for (int i=1;i<=m;i++)
{
need=a[i].t-(getsum(a[i].e)-getsum(a[i].b-1));
for (int j=a[i].e;j>=a[i].b;j--)
{
if (need<=0) break;
if (!f[j])
{
f[j]=1; need--;
modify(j); ans++;
}
}
}
printf("%d\n",ans);
return 0;
}