题目描述
丽江河边有n家很有特色的客栈,客栈按照其位置顺序从1到n编号。
每家客栈都按照某一种色调进行装饰(总共k种,用整数0 ~ k-1表示),且每家客栈都设有一间咖啡店,每家咖啡店均有各自的最低消费。
两位游客一起去丽江旅游,他们喜欢相同的色调,又想尝试两个不同的客栈,因此决定分别住在色调相同的两家客栈中。
晚上,他们打算选择一间咖啡店喝咖啡,要求咖啡店位于两人住的两家客栈之间(包括他们住的客栈),且咖啡店的最低消费不超过p。
他们想知道总共有多少种选择住宿的方案,保证晚上可以找到一间最低消费不超过p元的咖啡店小聚。
输入格式
第一行三个整数n,k,p,每两个整数之间用一个空格隔开,分别表示客栈的个数,色调的数目和能接受的最低消费的最高值;
接下来的n行,第i+1行两个整数,之间用一个空格隔开,分别表示i号客栈的装饰色调和i号客栈的咖啡店的最低消费。
样例
输入样例:
5 2 3
0 5
1 3
0 2
1 4
1 5
输出样例:
3
算法1
(暴力枚举)
思路讲解:萌新第一次写题解,大佬勿喷qaq~!先把题目过了一遍在看看数据范围,我的天二十万。一开始想的暴力枚举肯定过不了。怎么办怎么办!!!没事我们冷静来思考一下题目的意思,在看看暴力枚举的代码就会发现
一:如果客栈自身的咖啡店比<=p的话,那意思就是说它的后面有多少和他装饰一样的客栈就有多少方案。
二:如果一的条件不满足的话。那我们在仔细思考一下。我们暴力的第二个循环j找有没有和i相同的客栈,那如果我们找到了可以喝咖啡的客栈但还没找到和i装饰同的客栈。那现在这个问题是不是和第一优化一样了?意思就是说我找到了可以喝咖啡的客栈,但还没找到和我一样的客栈就直接加上后面和i相同装饰的客栈数。
三:然后如果一,二都不满足就直接枚举一遍即可。
四:然后然后然后以600ms完美Ac。
总结:这样的题可以分成很多子问题,当数据大的时候就找出可以剪枝的地方进行优化。这方法很暴力但是可以拿多点分。(和我一样的萌新强力推荐哦~)。
C++ 代码
#include<bits/stdc++.h>
using namespace std;
const int N=2000010;
map<int,int>ch;
int a[N],b[N],c[N],t[N],ai[N];
int n,m,k,ans,tot;
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i],&b[i]);
ch[a[i]]=max(ch[a[i]],i);
c[a[i]]++;
}
for(int i=1;i<=n;i++)
{
int ll=1,o=ch[a[i]];
c[a[i]]--;
if(b[i]<=k){ans+=c[a[i]];continue;}//优化一如果自身就可以喝咖啡直接加上后面相同的客栈数
for(int j=i+1;j<=n;j++)
{
if(ll&&b[j]<=k){ans+=c[a[i]];break;}//优化二如果我找到了可以喝咖啡的客栈但没找到和我一样的客栈就直接加上后面的客栈数
if(a[i]==a[j])//否则就枚举
{
ll=0;
for(int l=i;l<=j;l++){if(b[l]<=k){ans++;break;}}
}
}
}
printf("%d",ans);
}