题意:
有若干个区间,若干种数,每个数告诉你有多少个。
然后一个数可以被放到一个x∈该区间 的区间,问最多有多少个区间可以被放。
题解:
显然我们可以用二分图最大匹配做,水题。
但是此题有别的技巧、
就是我们可以贪心进行处理。
首先我们考虑到需要将两种数都排个序。
然后再进行贪心。
一种错误的贪心法是单调队列式贪心,就是记录个top,然后单调往后推。
这个不仔细想还不知道它是错的。
额,至于卡它的数据,,我可以提供给你一个错误代码和一个拍子,你们可以自己拍一组数据出来,很高效。
这里贴一份错误代码:
#include
#include
#include
#include
#define N 3000
#define inf 0x3f3f3f3f
using namespace std;
int n,m,ans,i;
struct KSD
{
int x,y;
bool operator < (const KSD &a)const{return x==a.x?(y
这里贴一份数据生成器
#include
#include
#include
#include
#include
#define N 10
#define inf 0x3f3f3f3f
using namespace std;
int n,m;
int main()
{
srand((unsigned)time(NULL));
int i,j,k;
int a,b,c;
n=rand()%N+1;
m=rand()%4+1;
printf("%d %d\n",n,m);
for(i=1;i<=n;i++)
{
a=rand()%N+1;
b=rand()%N+a;
printf("%d %d\n",a,b);
}
for(i=1;i<=m;i++)
{
a=rand()%(N*2)+1;
b=rand()%3+1;
printf("%d %d\n",a,b);
}
return 0;
}
这里贴个拍子
#include
#include
#include
#include
#include
#include
#define N 3000
using namespace std;
int main()
{
int i,g;
system("g++ std.cpp -o std -g");
system("g++ my.cpp -o my -g");
system("g++ rand.cpp -o rand -g");
for(g=1;g<=N;g++)
{
printf("Case %d : ",g);
system("rand>test.in");
clock_t j=clock();
system("my my.out");
clock_t k=clock();
printf("my_use : %03dms ",k-j);
system("std std.out");
printf("std_use : %03dms ",clock()-k);
if(system("fc std.out my.out >NULL")==0){puts("result : AC");}
else
{
puts("WAWAWAWAWAWAWAWA!!!!!!!!");
system("start test.in");
return 0;
}
}
puts("");
puts("****,please try again");
return 0;
}
拿上述的东西,再找个标程就可以pai了。
下面说一下正确思路。
首先按照顺序我们可以知道哪些区间的下界满足条件,那么就只需要上界也满足条件就行了。
因为数递增,所以如果当前的某个可用区间的上界比当前数小,那么以后也不可能满足了,就可以弹出去。
这样通过优先队列可以得到一个上界满足且最小的区间,这个区间则可以被计入答案。
思想说了个大概,没懂就看代码吧。
#include
#include
#include
#include
#include
#define N 3000
#define inf 0x3f3f3f3f
using namespace std;
int n,m,ans,i;
priority_queuepq;
struct KSD
{
int x,y;
bool operator < (const KSD &a)const{return x==a.x?(y=oil[i].x)ans++,oil[i].y--;
pq.pop();
}
}
printf("%d\n",ans);
return 0;
}